Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e77c8157ae
|
||
|
|
cb6724baab
|
||
|
|
cbd3c0a575 | ||
|
|
e1ac2777f3 | ||
|
|
900f499932 |
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v0.4.4
|
||||||
|
- Fix some failing tests
|
||||||
|
- Lowercase the domain when normalizing an account
|
||||||
|
|
||||||
## v0.4.3
|
## v0.4.3
|
||||||
- Fix hashtag not working in a mention
|
- Fix hashtag not working in a mention
|
||||||
|
|
||||||
|
|||||||
Generated
+1
-1
@@ -328,7 +328,7 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fedigroups"
|
name = "fedigroups"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fedigroups"
|
name = "fedigroups"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
|
|||||||
@@ -2,25 +2,21 @@ use std::cmp::Ordering;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use elefren::{FediClient, SearchType, StatusBuilder};
|
|
||||||
use elefren::entities::account::Account;
|
use elefren::entities::account::Account;
|
||||||
use elefren::entities::prelude::Status;
|
use elefren::entities::prelude::Status;
|
||||||
use elefren::status_builder::Visibility;
|
use elefren::status_builder::Visibility;
|
||||||
|
use elefren::{FediClient, SearchType, StatusBuilder};
|
||||||
|
|
||||||
use crate::command::{RE_NOBOT_TAG, StatusCommand};
|
use crate::command::{StatusCommand, RE_NOBOT_TAG};
|
||||||
use crate::error::GroupError;
|
use crate::error::GroupError;
|
||||||
use crate::group_handler::GroupHandle;
|
use crate::group_handler::GroupHandle;
|
||||||
use crate::store::CommonConfig;
|
|
||||||
use crate::store::group_config::GroupConfig;
|
use crate::store::group_config::GroupConfig;
|
||||||
|
use crate::store::CommonConfig;
|
||||||
use crate::tr::TranslationTable;
|
use crate::tr::TranslationTable;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use crate::utils::{LogError, normalize_acct, VisExt};
|
use crate::utils::{normalize_acct, LogError, VisExt};
|
||||||
|
|
||||||
use crate::{
|
use crate::{grp_debug, grp_info, grp_warn};
|
||||||
grp_debug,
|
|
||||||
grp_warn,
|
|
||||||
grp_info
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ProcessMention<'a> {
|
pub struct ProcessMention<'a> {
|
||||||
status: Status,
|
status: Status,
|
||||||
@@ -149,8 +145,7 @@ impl<'a> ProcessMention<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn reblog_status(&self) {
|
async fn reblog_status(&self) {
|
||||||
self.client.reblog(&self.status.id)
|
self.client.reblog(&self.status.id).await.log_error("Failed to reblog status");
|
||||||
.await.log_error("Failed to reblog status");
|
|
||||||
self.delay_after_post().await;
|
self.delay_after_post().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +670,11 @@ impl<'a> ProcessMention<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if self.config.is_member_only() {
|
if self.config.is_member_only() {
|
||||||
self.add_reply(crate::tr!(self, "help_group_info_closed", membership = &membership_line));
|
self.add_reply(crate::tr!(
|
||||||
|
self,
|
||||||
|
"help_group_info_closed",
|
||||||
|
membership = &membership_line
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
self.add_reply(crate::tr!(self, "help_group_info_open", membership = &membership_line));
|
self.add_reply(crate::tr!(self, "help_group_info_open", membership = &membership_line));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub struct GroupInternal {
|
|||||||
impl Default for GroupInternal {
|
impl Default for GroupInternal {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
recently_seen_notif_statuses: VecDeque::new()
|
recently_seen_notif_statuses: VecDeque::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,8 +552,7 @@ impl GroupHandle {
|
|||||||
|
|
||||||
self.config.set_member(notif_acct, true).log_error("Fail add a member");
|
self.config.set_member(notif_acct, true).log_error("Fail add a member");
|
||||||
|
|
||||||
crate::tr!(self, "mention_prefix", user = notif_acct)
|
crate::tr!(self, "mention_prefix", user = notif_acct) + &crate::tr!(self, "welcome_public")
|
||||||
+ &crate::tr!(self, "welcome_public")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let post = StatusBuilder::new()
|
let post = StatusBuilder::new()
|
||||||
|
|||||||
+1
-3
@@ -76,9 +76,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let default_level = 3;
|
let default_level = 3;
|
||||||
|
|
||||||
let level = (
|
let level = (default_level as isize + args.occurrences_of("verbose") as isize
|
||||||
default_level as isize
|
|
||||||
+ args.occurrences_of("verbose") as isize
|
|
||||||
- args.occurrences_of("quiet") as isize)
|
- args.occurrences_of("quiet") as isize)
|
||||||
.clamp(0, LEVELS.len() as isize) as usize;
|
.clamp(0, LEVELS.len() as isize) as usize;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use crate::store::DEFAULT_LOCALE_NAME;
|
use crate::store::DEFAULT_LOCALE_NAME;
|
||||||
use crate::tr::TranslationTable;
|
use crate::tr::TranslationTable;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
@@ -55,7 +55,7 @@ impl CommonConfig {
|
|||||||
pub fn tr(&self, lang: &str) -> &TranslationTable {
|
pub fn tr(&self, lang: &str) -> &TranslationTable {
|
||||||
match self.tr.get(lang) {
|
match self.tr.get(lang) {
|
||||||
Some(tr) => tr,
|
Some(tr) => tr,
|
||||||
None => self.tr.get(DEFAULT_LOCALE_NAME).expect("default locale is not loaded")
|
None => self.tr.get(DEFAULT_LOCALE_NAME).expect("default locale is not loaded"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-12
@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use elefren::AppData;
|
use elefren::AppData;
|
||||||
|
|
||||||
use crate::error::GroupError;
|
use crate::error::GroupError;
|
||||||
use crate::store::{DEFAULT_LOCALE_NAME, CommonConfig};
|
use crate::store::{CommonConfig, DEFAULT_LOCALE_NAME};
|
||||||
use crate::tr::TranslationTable;
|
use crate::tr::TranslationTable;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@@ -259,7 +259,11 @@ impl GroupConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// (re)init using new authorization
|
/// (re)init using new authorization
|
||||||
pub(crate) async fn initialize_by_appdata(acct: String, appdata: AppData, group_dir: PathBuf) -> Result<(), GroupError> {
|
pub(crate) async fn initialize_by_appdata(
|
||||||
|
acct: String,
|
||||||
|
appdata: AppData,
|
||||||
|
group_dir: PathBuf,
|
||||||
|
) -> Result<(), GroupError> {
|
||||||
if !group_dir.is_dir() {
|
if !group_dir.is_dir() {
|
||||||
debug!("Creating group directory");
|
debug!("Creating group directory");
|
||||||
tokio::fs::create_dir_all(&group_dir).await?;
|
tokio::fs::create_dir_all(&group_dir).await?;
|
||||||
@@ -306,7 +310,12 @@ impl GroupConfig {
|
|||||||
/* state */
|
/* state */
|
||||||
let state = load_or_create_state_file(state_path).await?;
|
let state = load_or_create_state_file(state_path).await?;
|
||||||
|
|
||||||
let g = GroupConfig { config, control, state, _group_tr: TranslationTable::new() };
|
let g = GroupConfig {
|
||||||
|
config,
|
||||||
|
control,
|
||||||
|
state,
|
||||||
|
_group_tr: TranslationTable::new(),
|
||||||
|
};
|
||||||
g.warn_of_bad_config();
|
g.warn_of_bad_config();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -338,7 +347,12 @@ impl GroupConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let g = GroupConfig { config, control, state, _group_tr: tr };
|
let g = GroupConfig {
|
||||||
|
config,
|
||||||
|
control,
|
||||||
|
state,
|
||||||
|
_group_tr: tr,
|
||||||
|
};
|
||||||
g.warn_of_bad_config();
|
g.warn_of_bad_config();
|
||||||
Ok(g)
|
Ok(g)
|
||||||
}
|
}
|
||||||
@@ -458,7 +472,7 @@ impl GroupConfig {
|
|||||||
/// Check if the user's server is banned
|
/// Check if the user's server is banned
|
||||||
fn is_users_server_banned(&self, acct: &str) -> bool {
|
fn is_users_server_banned(&self, acct: &str) -> bool {
|
||||||
let server = acct_to_server(acct);
|
let server = acct_to_server(acct);
|
||||||
self.is_server_banned(server)
|
self.is_server_banned(&server)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn can_write(&self, acct: &str) -> bool {
|
pub(crate) fn can_write(&self, acct: &str) -> bool {
|
||||||
@@ -574,8 +588,8 @@ impl GroupConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn acct_to_server(acct: &str) -> &str {
|
fn acct_to_server(acct: &str) -> String {
|
||||||
acct.split('@').nth(1).unwrap_or_default()
|
crate::utils::acct_to_server(acct).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -588,15 +602,15 @@ mod tests {
|
|||||||
config: Default::default(),
|
config: Default::default(),
|
||||||
control: Default::default(),
|
control: Default::default(),
|
||||||
state: Default::default(),
|
state: Default::default(),
|
||||||
_group_tr: Default::default()
|
_group_tr: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_acct_to_server() {
|
fn test_acct_to_server() {
|
||||||
assert_eq!("pikachu.rocks", acct_to_server("raichu@pikachu.rocks"));
|
assert_eq!("pikachu.rocks".to_string(), acct_to_server("raichu@pikachu.rocks"));
|
||||||
assert_eq!("pikachu.rocks", acct_to_server("m@pikachu.rocks"));
|
assert_eq!("pikachu.rocks".to_string(), acct_to_server("m@pikachu.rocks"));
|
||||||
assert_eq!("", acct_to_server("what"));
|
assert_eq!("".to_string(), acct_to_server("what"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -666,13 +680,15 @@ mod tests {
|
|||||||
assert!(!group.is_banned("piggo@piggo.space"), "user not banned by default");
|
assert!(!group.is_banned("piggo@piggo.space"), "user not banned by default");
|
||||||
|
|
||||||
group.ban_user("piggo@piggo.space", true).unwrap();
|
group.ban_user("piggo@piggo.space", true).unwrap();
|
||||||
assert!(group.is_member("piggo@piggo.space"), "still member even if banned");
|
assert!(!group.is_member("piggo@piggo.space"), "banned user is kicked");
|
||||||
assert!(group.is_banned("piggo@piggo.space"), "banned user is banned");
|
assert!(group.is_banned("piggo@piggo.space"), "banned user is banned");
|
||||||
|
|
||||||
assert!(!group.can_write("piggo@piggo.space"), "banned member can't post");
|
assert!(!group.can_write("piggo@piggo.space"), "banned member can't post");
|
||||||
|
|
||||||
// unban
|
// unban
|
||||||
group.ban_user("piggo@piggo.space", false).unwrap();
|
group.ban_user("piggo@piggo.space", false).unwrap();
|
||||||
|
assert!(!group.can_write("piggo@piggo.space"), "unbanned member is still kicked");
|
||||||
|
group.set_member("piggo@piggo.space", true).unwrap();
|
||||||
assert!(group.can_write("piggo@piggo.space"), "un-ban works");
|
assert!(group.can_write("piggo@piggo.space"), "un-ban works");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -9,9 +9,9 @@ use crate::group_handler::{GroupHandle, GroupInternal};
|
|||||||
|
|
||||||
pub mod common_config;
|
pub mod common_config;
|
||||||
pub mod group_config;
|
pub mod group_config;
|
||||||
|
use crate::tr::TranslationTable;
|
||||||
pub use common_config::CommonConfig;
|
pub use common_config::CommonConfig;
|
||||||
pub use group_config::GroupConfig;
|
pub use group_config::GroupConfig;
|
||||||
use crate::tr::TranslationTable;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ConfigStore {
|
pub struct ConfigStore {
|
||||||
@@ -214,7 +214,7 @@ impl ConfigStore {
|
|||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
let locale_name = path.file_stem().unwrap_or_default().to_string_lossy();
|
let locale_name = path.file_stem().unwrap_or_default().to_string_lossy();
|
||||||
self.load_locale(&locale_name, &String::from_utf8_lossy(&f), false);
|
self.load_locale(&locale_name, &String::from_utf8_lossy(&f), false);
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to read locale file {}: {}", path.display(), e);
|
error!("Failed to read locale file {}: {}", path.display(), e);
|
||||||
}
|
}
|
||||||
@@ -234,10 +234,12 @@ impl ConfigStore {
|
|||||||
for (k, v) in def_tr.entries() {
|
for (k, v) in def_tr.entries() {
|
||||||
if !tr.translation_exists(k) {
|
if !tr.translation_exists(k) {
|
||||||
if self.config.validate_locales {
|
if self.config.validate_locales {
|
||||||
warn!("locale \"{}\" is missing \"{}\", default: {:?}",
|
warn!(
|
||||||
|
"locale \"{}\" is missing \"{}\", default: {:?}",
|
||||||
locale_name,
|
locale_name,
|
||||||
k,
|
k,
|
||||||
def_tr.get_translation_raw(k).unwrap());
|
def_tr.get_translation_raw(k).unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
tr.add_translation(k, v);
|
tr.add_translation(k, v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ impl TranslationTable {
|
|||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
None => key.to_owned()
|
None => key.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,6 @@ mod tests {
|
|||||||
assert_eq!("xxx", tr.subs("xxx", &[]));
|
assert_eq!("xxx", tr.subs("xxx", &[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subs() {
|
fn subs() {
|
||||||
let mut tr = TranslationTable::new();
|
let mut tr = TranslationTable::new();
|
||||||
|
|||||||
+6
-6
@@ -19,8 +19,8 @@ impl<V, E: Error> LogError for Result<V, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn acct_to_server(acct: &str) -> Option<&str> {
|
pub(crate) fn acct_to_server(acct: &str) -> Option<String> {
|
||||||
acct.trim_start_matches('@').split('@').nth(1)
|
acct.trim_start_matches('@').split('@').nth(1).map(|s| s.to_lowercase())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn normalize_acct(acct: &str, group: &str) -> Result<String, GroupError> {
|
pub(crate) fn normalize_acct(acct: &str, group: &str) -> Result<String, GroupError> {
|
||||||
@@ -45,8 +45,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_acct_to_server() {
|
fn test_acct_to_server() {
|
||||||
assert_eq!(Some("novak"), acct_to_server("pepa@novak"));
|
assert_eq!(Some("novak".to_string()), acct_to_server("pepa@novak"));
|
||||||
assert_eq!(Some("banana.co.uk"), acct_to_server("@pepa@banana.co.uk"));
|
assert_eq!(Some("banana.co.uk".to_string()), acct_to_server("@pepa@banana.co.uk"));
|
||||||
assert_eq!(None, acct_to_server("probably_local"));
|
assert_eq!(None, acct_to_server("probably_local"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ mod test {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok("piggo@piggo.space".into()),
|
Ok("piggo@piggo.space".into()),
|
||||||
normalize_acct("piGGgo@pIggo.spaCe", "uhh")
|
normalize_acct("piGGo@pIggo.spaCe", "uhh")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok("piggo@banana.nana".into()),
|
Ok("piggo@banana.nana".into()),
|
||||||
normalize_acct("piGGgo", "foo@baNANA.nana")
|
normalize_acct("piGGo", "foo@baNANA.nana")
|
||||||
);
|
);
|
||||||
assert_eq!(Err(GroupError::BadConfig("_".into())), normalize_acct("piggo", "uhh"));
|
assert_eq!(Err(GroupError::BadConfig("_".into())), normalize_acct("piggo", "uhh"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user