My instance has a spam problem. A user signs up and drops 5+ spam notes before I can suspend them. The notes they create are not deleted or hidden when their account is suspended.
An instance admin (and mods?) must have the ability to remove and/or hide notes from the instance timelines. When a user is suspended, all their posts should (optionally) disappear.
It would be a awesome. Now I do it with a small python script I wrote:
misskey@slippy:~$ cat purge-spammer.py
#!/usr/bin/env python3
import yaml
import sys
import psycopg2
class Terminator:
def __enter__(self):
self.connection = self.get_connection()
return self
def __exit__(self, *args):
self.connection.close()
def read_database_config(self):
with open('/home/misskey/misskey/.config/default.yml') as f:
return yaml.safe_load(f)
def get_connection(self):
c = self.read_database_config()['db']
return psycopg2.connect(f"dbname={c['db']} user={c['user']} password={c['pass']}")
def get_id(self, username):
cursor = self.connection.cursor()
cursor.execute('select "id" from "user" where "username" = %s and "host" is null', (username,))
uid = cursor.fetchone()[0]
cursor.close()
return uid
def number_of_notes(self, uid):
cursor = self.connection.cursor()
cursor.execute('select "notesCount" from "user" where "id" = %s', (uid,))
count = cursor.fetchone()[0]
cursor.close()
return count
def purge(self, username, reason):
uid = self.get_id(username)
non = self.number_of_notes(uid)
print(f"Number of notes: {non}")
answer = None
print(f"[?] Terminating {username}; reason: {reason}")
while answer not in ("yes", "no"):
answer = input("Are you sure? [yes or no] ")
if answer == "yes":
break
elif answer == "no":
return
else:
print("Please enter yes or no.")
cursor = self.connection.cursor()
cursor.execute('delete from "note" where "userId" = %s', (uid,))
cursor.execute('update "user" set "notesCount" = 0, "isSuspended" = true, "isSilenced" = true where "id" = %s', (uid,))
reason = f'Suspended; Silenced; Purged; Reason: {reason}'
cursor.execute('update "user_profile" set "description" = %s where "userId" = %s', (reason, uid))
cursor.close()
self.connection.commit()
print(f"[+] No more '{username}'!")
if __name__ == '__main__':
if len(sys.argv) != 3:
print(f'> {sys.argv[0]} <username> <reason>')
else:
with Terminator() as t800:
t800.purge(sys.argv[1], sys.argv[2])
In action:
misskey@slippy:~$ ./purge-spammer.py findcarvip Spam
Number of notes: 0
[?] Terminating findcarvip; reason: Spam
Are you sure? [yes or no] yes
[+] No more 'findcarvip'!
(number of notes is zero because it was already been purged).
And that's how it looks like on their profile:

I was thinking about changing the profile picture too, but then I decided just leave as it is, i'm lazy for that.
I hope it helps others until this feature lands on the UI somewhere. (ofc it does not propagate the deleted notes to the federated network, but that's what I can do to prevent their actions)
FYI: Currently this is not implemented in (only) client side. If you are moderator (or higher), you should be able to delete other user's notes via API call.
Alternately, You can use v11 client app (https://v11.misskey.io/ your-instance-domain) until this is get implemented.
Thanks @yitsushi , that worked. I had to add host=localhost to the DB connection or it failed, dunno what's up with that (I don't know python, or postgres very well).
EDIT: Also thank you for that explanation @u1-liquid , I appreciate it.
Most helpful comment
Thanks @yitsushi , that worked. I had to add host=localhost to the DB connection or it failed, dunno what's up with that (I don't know python, or postgres very well).
EDIT: Also thank you for that explanation @u1-liquid , I appreciate it.