mirror of
https://git.ondrovo.com/MightyPork/group-actor.git
synced 2024-12-18 13:16:45 +00:00
readme, some fixes
This commit is contained in:
parent
2b84e5eeb0
commit
957f0dbb3b
10 changed files with 118 additions and 59 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,7 +1,16 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v0.2
|
## v0.2.2
|
||||||
|
- All hashtags, server names and handles are now lowercased = case-insensitive
|
||||||
|
- Prevent the `-a` flag overwriting existing group in the config
|
||||||
|
- Update the help text
|
||||||
|
- `/i` now works in hashtag posts
|
||||||
|
- `/add user` and `/remove user` now correctly follow/unfollow
|
||||||
|
|
||||||
|
## v0.2.1
|
||||||
|
- More reliable websocket reconnect, workaround for pleroma socket going silent
|
||||||
|
|
||||||
|
## v0.2.0
|
||||||
- Add hashtag boosting and back-follow/unfollow
|
- Add hashtag boosting and back-follow/unfollow
|
||||||
- Add hashtag commands
|
- Add hashtag commands
|
||||||
- Code reorganization
|
- Code reorganization
|
||||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -276,7 +276,7 @@ checksum = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "elefren"
|
name = "elefren"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
source = "git+https://git.ondrovo.com/MightyPork/elefren-fork.git?rev=54a0e55#54a0e55964784368864f36580c5630f730bf72dc"
|
source = "git+https://git.ondrovo.com/MightyPork/elefren-fork.git?rev=a0ebb46#a0ebb46542ede2d235ca6094135a6d6d01d0ecb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"doc-comment",
|
"doc-comment",
|
||||||
|
@ -328,7 +328,7 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fedigroups"
|
name = "fedigroups"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fedigroups"
|
name = "fedigroups"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
|
@ -10,7 +10,7 @@ build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
#elefren = { path = "../elefren22-fork" }
|
#elefren = { path = "../elefren22-fork" }
|
||||||
elefren = { git = "https://git.ondrovo.com/MightyPork/elefren-fork.git", rev = "54a0e55" }
|
elefren = { git = "https://git.ondrovo.com/MightyPork/elefren-fork.git", rev = "a0ebb46" }
|
||||||
|
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ Any user (member in member-only groups) can post to the group by mentioning the
|
||||||
|
|
||||||
### Group hashtags
|
### Group hashtags
|
||||||
|
|
||||||
Admins can add hashtags to the group config (`/add #hashtag`, remove the same way: `/remove #hashtag`).
|
Admins can add hashtags to the group config (`/add #hashtag`, remove the same way: `/remove #hashtag`). Hashtags are case-insensitive.
|
||||||
|
|
||||||
When a *group member* posts one of the group hashtags, the group will reblog it. This is a nicer way to share posts, you don't have to mention the group user at all.
|
When a *group member* posts one of the group hashtags, the group will reblog it. This is a nicer way to share posts, you don't have to mention the group user at all.
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ pub fn parse_status_tags(content: &str) -> Vec<String> {
|
||||||
let mut tags = vec![];
|
let mut tags = vec![];
|
||||||
for c in RE_A_HASHTAG.captures_iter(&content) {
|
for c in RE_A_HASHTAG.captures_iter(&content) {
|
||||||
if let Some(s) = c.get(1) {
|
if let Some(s) = c.get(1) {
|
||||||
tags.push(s.as_str().to_string())
|
tags.push(s.as_str().to_lowercase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +150,11 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let content = voca_rs::strip::strip_tags(&content);
|
let content = voca_rs::strip::strip_tags(&content);
|
||||||
debug!("Stripped tags: {}", content);
|
debug!("Stripped tags: {}", content);
|
||||||
|
|
||||||
|
if !content.contains('/') && !content.contains('\\') {
|
||||||
|
// No slash = no command
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
// short-circuiting commands
|
// short-circuiting commands
|
||||||
|
|
||||||
if RE_IGNORE.is_match(&content) {
|
if RE_IGNORE.is_match(&content) {
|
||||||
|
@ -221,7 +226,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("BAN USER: {}", s);
|
debug!("BAN USER: {}", s);
|
||||||
commands.push(StatusCommand::BanUser(s.to_owned()));
|
commands.push(StatusCommand::BanUser(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,21 +235,21 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("UNBAN USER: {}", s);
|
debug!("UNBAN USER: {}", s);
|
||||||
commands.push(StatusCommand::UnbanUser(s.to_owned()));
|
commands.push(StatusCommand::UnbanUser(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for c in RE_BAN_SERVER.captures_iter(&content) {
|
for c in RE_BAN_SERVER.captures_iter(&content) {
|
||||||
if let Some(s) = c.get(1) {
|
if let Some(s) = c.get(1) {
|
||||||
debug!("BAN SERVER: {}", s.as_str());
|
debug!("BAN SERVER: {}", s.as_str());
|
||||||
commands.push(StatusCommand::BanServer(s.as_str().to_owned()));
|
commands.push(StatusCommand::BanServer(s.as_str().to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for c in RE_UNBAN_SERVER.captures_iter(&content) {
|
for c in RE_UNBAN_SERVER.captures_iter(&content) {
|
||||||
if let Some(s) = c.get(1) {
|
if let Some(s) = c.get(1) {
|
||||||
debug!("UNBAN SERVER: {}", s.as_str());
|
debug!("UNBAN SERVER: {}", s.as_str());
|
||||||
commands.push(StatusCommand::UnbanServer(s.as_str().to_owned()));
|
commands.push(StatusCommand::UnbanServer(s.as_str().to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +258,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("ADD MEMBER: {}", s);
|
debug!("ADD MEMBER: {}", s);
|
||||||
commands.push(StatusCommand::AddMember(s.to_owned()));
|
commands.push(StatusCommand::AddMember(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +267,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("REMOVE USER: {}", s);
|
debug!("REMOVE USER: {}", s);
|
||||||
commands.push(StatusCommand::RemoveMember(s.to_owned()));
|
commands.push(StatusCommand::RemoveMember(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +275,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
if let Some(s) = c.get(1) {
|
if let Some(s) = c.get(1) {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
debug!("ADD TAG: {}", s);
|
debug!("ADD TAG: {}", s);
|
||||||
commands.push(StatusCommand::AddTag(s.to_owned()));
|
commands.push(StatusCommand::AddTag(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +283,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
if let Some(s) = c.get(1) {
|
if let Some(s) = c.get(1) {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
debug!("REMOVE TAG: {}", s);
|
debug!("REMOVE TAG: {}", s);
|
||||||
commands.push(StatusCommand::RemoveTag(s.to_owned()));
|
commands.push(StatusCommand::RemoveTag(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +292,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("ADD ADMIN: {}", s);
|
debug!("ADD ADMIN: {}", s);
|
||||||
commands.push(StatusCommand::GrantAdmin(s.to_owned()));
|
commands.push(StatusCommand::GrantAdmin(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +301,7 @@ pub fn parse_slash_commands(content: &str) -> Vec<StatusCommand> {
|
||||||
let s = s.as_str();
|
let s = s.as_str();
|
||||||
let s = s.trim_start_matches('@');
|
let s = s.trim_start_matches('@');
|
||||||
debug!("REMOVE ADMIN: {}", s);
|
debug!("REMOVE ADMIN: {}", s);
|
||||||
commands.push(StatusCommand::RemoveAdmin(s.to_owned()));
|
commands.push(StatusCommand::RemoveAdmin(s.to_lowercase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,17 @@ impl<'a> ProcessMention<'a> {
|
||||||
Err(e.into())
|
Err(e.into())
|
||||||
}
|
}
|
||||||
Ok(Ok(res)) => {
|
Ok(Ok(res)) => {
|
||||||
|
debug!("Result: {:#?}", res);
|
||||||
|
|
||||||
if let Some(item) = res.accounts.into_iter().next() {
|
if let Some(item) = res.accounts.into_iter().next() {
|
||||||
debug!("Search done, account found");
|
let acct_normalized = normalize_acct(&item.acct, &self.group_acct)?;
|
||||||
Ok(Some(item.id))
|
if acct_normalized == acct {
|
||||||
|
debug!("Search done, account found: {}", item.acct);
|
||||||
|
Ok(Some(item.id))
|
||||||
|
} else {
|
||||||
|
warn!("Search done but found wrong account: {}", item.acct);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("Search done, nothing found");
|
debug!("Search done, nothing found");
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -80,12 +88,14 @@ impl<'a> ProcessMention<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn follow_user(&self, id: &str) -> Result<(), GroupError> {
|
async fn follow_user_by_id(&self, id: &str) -> Result<(), GroupError> {
|
||||||
|
debug!("Trying to follow user #{}", id);
|
||||||
self.client.follow(id).await?;
|
self.client.follow(id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unfollow_user(&self, id: &str) -> Result<(), GroupError> {
|
async fn unfollow_user_by_id(&self, id: &str) -> Result<(), GroupError> {
|
||||||
|
debug!("Trying to unfollow user #{}", id);
|
||||||
self.client.unfollow(id).await?;
|
self.client.unfollow(id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -373,13 +383,15 @@ impl<'a> ProcessMention<'a> {
|
||||||
match self.config.set_member(&u, true) {
|
match self.config.set_member(&u, true) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.add_reply(format!("User {} added to the group!", u));
|
self.add_reply(format!("User {} added to the group!", u));
|
||||||
self.follow_user(&self.status_user_id)
|
self.follow_by_acct(&u)
|
||||||
.await.log_error("Failed to follow");
|
.await.log_error("Failed to follow");
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.add_reply(format!("Failed to add user {} to group: {}", u, e));
|
self.add_reply(format!("Failed to add user {} to group: {}", u, e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
debug!("User was already a member");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.add_reply("Only admins can manage members");
|
self.add_reply("Only admins can manage members");
|
||||||
|
@ -505,49 +517,48 @@ impl<'a> ProcessMention<'a> {
|
||||||
self.add_reply("This is a public-access group. ");
|
self.add_reply("This is a public-access group. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.config.can_write(&self.status_acct) {
|
if self.is_admin {
|
||||||
if self.is_admin {
|
self.add_reply("*You are an admin.*");
|
||||||
self.add_reply("*You are an admin.*");
|
} else if self.config.is_member(&self.status_acct) {
|
||||||
} else {
|
self.add_reply("*You are a member.*");
|
||||||
self.add_reply("*You are a member.*");
|
} else if self.config.is_member_only() {
|
||||||
}
|
self.add_reply("*You are not a member, ask one of the admins to add you.*");
|
||||||
} else {
|
} else {
|
||||||
if self.config.is_member_only() {
|
self.add_reply("*You are not a member, follow or use /join to join the group.*");
|
||||||
self.add_reply("*You are not a member, ask one of the admins to add you.*");
|
|
||||||
} else {
|
|
||||||
self.add_reply("*You are not a member, follow or use /join to join the group.*");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add_reply("\n\
|
self.add_reply("\n\
|
||||||
To share an original post, mention the group user.\n\
|
To share a post, mention the group user or use one of the group hashtags. \
|
||||||
Replies and mentions with commands won't be shared.\n\
|
Replies and mentions with commands won't be shared.\n\
|
||||||
\n\
|
\n\
|
||||||
**Supported commands:**\n\
|
**Supported commands:**\n\
|
||||||
`/boost, /b` - boost the replied-to post into the group\n\
|
`/boost`, `/b` - boost the replied-to post into the group\n\
|
||||||
`/ignore, /i` - make the group completely ignore the post\n\
|
`/ignore`, `/i` - make the group ignore the post\n\
|
||||||
`/ping` - check that the service is alive\n\
|
`/ping` - check the service is alive\n\
|
||||||
|
`/tags` - show group hashtags\n\
|
||||||
`/join` - join the group\n\
|
`/join` - join the group\n\
|
||||||
`/leave` - leave the group");
|
`/leave` - leave the group");
|
||||||
|
|
||||||
if self.config.is_member_only() {
|
if self.config.is_member_only() {
|
||||||
self.add_reply("`/members, /who` - show group members / admins");
|
self.add_reply("`/members`, `/who` - show group members / admins");
|
||||||
} else {
|
} else {
|
||||||
self.add_reply("`/members, /who` - show group admins");
|
self.add_reply("`/members`, `/who` - show group admins");
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.is_admin {
|
if self.is_admin {
|
||||||
self.add_reply("\n\
|
self.add_reply("\n\
|
||||||
**Admin commands:**\n\
|
**Admin commands:**\n\
|
||||||
`/add user` - add a member (use e-mail style address)\n\
|
`/add user` - add a member (use e-mail style address)\n\
|
||||||
`/kick, /remove user` - kick a member\n\
|
`/remove user` - remove a member\n\
|
||||||
`/ban x` - ban a user or a server\n\
|
`/add #hashtag` - add a group hashtag\n\
|
||||||
|
`/remove #hashtag` - remove a group hashtag\n\
|
||||||
|
`/ban x` - ban a user or server\n\
|
||||||
`/unban x` - lift a ban\n\
|
`/unban x` - lift a ban\n\
|
||||||
`/op, /admin user` - grant admin rights\n\
|
`/admin user` - grant admin rights\n\
|
||||||
`/deop, /deadmin user` - revoke admin rights\n\
|
`/deadmin user` - revoke admin rights\n\
|
||||||
`/opengroup` - make member-only\n\
|
`/opengroup` - make member-only\n\
|
||||||
`/closegroup` - make public-access\n\
|
`/closegroup` - make public-access\n\
|
||||||
`/announce x` - make a public announcement from the rest of the status");
|
`/announce x` - make a public announcement from the rest of the status (without formatting)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +586,7 @@ impl<'a> ProcessMention<'a> {
|
||||||
// admin can leave but that's a bad idea
|
// admin can leave but that's a bad idea
|
||||||
let _ = self.config.set_member(&self.status_acct, false);
|
let _ = self.config.set_member(&self.status_acct, false);
|
||||||
self.add_reply("You're no longer a group member. Unfollow the group user to stop receiving group messages.");
|
self.add_reply("You're no longer a group member. Unfollow the group user to stop receiving group messages.");
|
||||||
self.unfollow_user(&self.status_user_id).await
|
self.unfollow_user_by_id(&self.status_user_id).await
|
||||||
.log_error("Failed to unfollow");
|
.log_error("Failed to unfollow");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,7 +596,7 @@ impl<'a> ProcessMention<'a> {
|
||||||
debug!("Already member or admin, try to follow-back again");
|
debug!("Already member or admin, try to follow-back again");
|
||||||
// Already a member, so let's try to follow the user
|
// Already a member, so let's try to follow the user
|
||||||
// again, maybe first time it failed
|
// again, maybe first time it failed
|
||||||
self.follow_user(&self.status_user_id).await
|
self.follow_user_by_id(&self.status_user_id).await
|
||||||
.log_error("Failed to follow");
|
.log_error("Failed to follow");
|
||||||
} else {
|
} else {
|
||||||
// Not a member yet
|
// Not a member yet
|
||||||
|
@ -598,7 +609,7 @@ impl<'a> ProcessMention<'a> {
|
||||||
self.append_admin_list_to_reply();
|
self.append_admin_list_to_reply();
|
||||||
} else {
|
} else {
|
||||||
// Open access, try to follow back
|
// Open access, try to follow back
|
||||||
self.follow_user(&self.status_user_id).await
|
self.follow_user_by_id(&self.status_user_id).await
|
||||||
.log_error("Failed to follow");
|
.log_error("Failed to follow");
|
||||||
|
|
||||||
// This only fails if the user is banned, but that is filtered above
|
// This only fails if the user is banned, but that is filtered above
|
||||||
|
@ -618,7 +629,15 @@ impl<'a> ProcessMention<'a> {
|
||||||
async fn unfollow_by_acct(&self, acct: &str) -> Result<(), GroupError> {
|
async fn unfollow_by_acct(&self, acct: &str) -> Result<(), GroupError> {
|
||||||
// Try to unfollow
|
// Try to unfollow
|
||||||
if let Ok(Some(id)) = self.lookup_acct_id(acct, true).await {
|
if let Ok(Some(id)) = self.lookup_acct_id(acct, true).await {
|
||||||
self.unfollow_user(&id).await?;
|
self.unfollow_user_by_id(&id).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn follow_by_acct(&self, acct: &str) -> Result<(), GroupError> {
|
||||||
|
// Try to unfollow
|
||||||
|
if let Ok(Some(id)) = self.lookup_acct_id(acct, false).await {
|
||||||
|
self.follow_user_by_id(&id).await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crate::error::GroupError;
|
||||||
use crate::store::ConfigStore;
|
use crate::store::ConfigStore;
|
||||||
use crate::store::data::GroupConfig;
|
use crate::store::data::GroupConfig;
|
||||||
use crate::utils::{LogError, normalize_acct, VisExt};
|
use crate::utils::{LogError, normalize_acct, VisExt};
|
||||||
|
use crate::command::StatusCommand;
|
||||||
|
|
||||||
mod handle_mention;
|
mod handle_mention;
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ impl GroupHandle {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a non-mention status
|
/// Handle a non-mention status for tags
|
||||||
async fn handle_status(&mut self, s: Status) -> Result<(), GroupError> {
|
async fn handle_status(&mut self, s: Status) -> Result<(), GroupError> {
|
||||||
debug!("Handling status #{}", s.id);
|
debug!("Handling status #{}", s.id);
|
||||||
let ts = s.timestamp_millis();
|
let ts = s.timestamp_millis();
|
||||||
|
@ -252,11 +253,22 @@ impl GroupHandle {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.in_reply_to_id.is_some() {
|
||||||
|
debug!("Status is a reply, discard");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if !s.content.contains('#') {
|
if !s.content.contains('#') {
|
||||||
debug!("No tags in status, discard");
|
debug!("No tags in status, discard");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let commands = crate::command::parse_slash_commands(&s.content);
|
||||||
|
if commands.contains(&StatusCommand::Ignore) {
|
||||||
|
debug!("Post has IGNORE command, discard");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let group_user = self.config.get_acct();
|
let group_user = self.config.get_acct();
|
||||||
let status_user = normalize_acct(&s.account.acct, group_user)?;
|
let status_user = normalize_acct(&s.account.acct, group_user)?;
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,13 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(handle) = args.value_of("auth") {
|
if let Some(handle) = args.value_of("auth") {
|
||||||
|
let handle = handle.to_lowercase();
|
||||||
let acct = handle.trim_start_matches('@');
|
let acct = handle.trim_start_matches('@');
|
||||||
|
|
||||||
|
if store.group_exists(acct).await {
|
||||||
|
anyhow::bail!("Group already exists in config!");
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(server) = acct_to_server(acct) {
|
if let Some(server) = acct_to_server(acct) {
|
||||||
let g = store
|
let g = store
|
||||||
.auth_new_group(NewGroupOptions {
|
.auth_new_group(NewGroupOptions {
|
||||||
|
|
|
@ -152,6 +152,10 @@ impl ConfigStore {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn group_exists(&self, acct : &str) -> bool {
|
||||||
|
self.data.read().await.groups.contains_key(acct)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub(crate) async fn get_group_config(&self, group: &str) -> Option<GroupConfig> {
|
pub(crate) async fn get_group_config(&self, group: &str) -> Option<GroupConfig> {
|
||||||
let c = self.data.read().await;
|
let c = self.data.read().await;
|
||||||
|
@ -191,10 +195,7 @@ impl ConfigStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_scopes() -> Scopes {
|
fn make_scopes() -> Scopes {
|
||||||
Scopes::read(scopes::Read::Accounts)
|
Scopes::read_all()
|
||||||
| Scopes::read(scopes::Read::Notifications)
|
|
||||||
| Scopes::read(scopes::Read::Statuses)
|
|
||||||
| Scopes::read(scopes::Read::Follows)
|
|
||||||
| Scopes::write(scopes::Write::Statuses)
|
| Scopes::write(scopes::Write::Statuses)
|
||||||
| Scopes::write(scopes::Write::Media)
|
| Scopes::write(scopes::Write::Media)
|
||||||
| Scopes::write(scopes::Write::Follows)
|
| Scopes::write(scopes::Write::Follows)
|
||||||
|
|
19
src/utils.rs
19
src/utils.rs
|
@ -1,4 +1,3 @@
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use elefren::status_builder::Visibility;
|
use elefren::status_builder::Visibility;
|
||||||
|
@ -24,14 +23,14 @@ pub(crate) fn acct_to_server(acct: &str) -> Option<&str> {
|
||||||
acct.trim_start_matches('@').split('@').nth(1)
|
acct.trim_start_matches('@').split('@').nth(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn normalize_acct<'a, 'g>(acct: &'a str, group: &'g str) -> Result<Cow<'a, str>, GroupError> {
|
pub(crate) fn normalize_acct(acct: &str, group: &str) -> Result<String, GroupError> {
|
||||||
let acct = acct.trim_start_matches('@');
|
let acct = acct.trim_start_matches('@').to_lowercase();
|
||||||
if acct_to_server(acct).is_some() {
|
if acct_to_server(&acct).is_some() {
|
||||||
// already has server
|
// already has server
|
||||||
Ok(Cow::Borrowed(acct))
|
Ok(acct)
|
||||||
} else if let Some(gs) = acct_to_server(group) {
|
} else if let Some(gs) = acct_to_server(group) {
|
||||||
// attach server from the group actor
|
// attach server from the group actor
|
||||||
Ok(Cow::Owned(format!("{}@{}", acct, gs)))
|
Ok(format!("{}@{}", acct, gs))
|
||||||
} else {
|
} else {
|
||||||
Err(GroupError::BadConfig(
|
Err(GroupError::BadConfig(
|
||||||
format!("Group acct {} is missing server!", group).into(),
|
format!("Group acct {} is missing server!", group).into(),
|
||||||
|
@ -81,6 +80,14 @@ mod test {
|
||||||
Ok("piggo@piggo.space".into()),
|
Ok("piggo@piggo.space".into()),
|
||||||
normalize_acct("piggo@piggo.space", "uhh")
|
normalize_acct("piggo@piggo.space", "uhh")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok("piggo@piggo.space".into()),
|
||||||
|
normalize_acct("piGGgo@pIggo.spaCe", "uhh")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok("piggo@banana.nana".into()),
|
||||||
|
normalize_acct("piGGgo", "foo@baNANA.nana")
|
||||||
|
);
|
||||||
assert_eq!(Err(GroupError::BadConfig("_".into())), normalize_acct("piggo", "uhh"));
|
assert_eq!(Err(GroupError::BadConfig("_".into())), normalize_acct("piggo", "uhh"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue