initial commit
This commit is contained in:
parent
5bc3d84b89
commit
604850a16b
131
cleansy.py
Normal file
131
cleansy.py
Normal file
|
@ -0,0 +1,131 @@
|
|||
import argparse
|
||||
from src.api.synapse import Synapse
|
||||
from src.api.media_info import get_media_info
|
||||
from src.api.user_info import get_user_info
|
||||
|
||||
|
||||
def get_user_media(_user_id, number=100, size=1024, order="media_length", direction="b"):
|
||||
user_info = synapse.get_user_info(_user_id).json()
|
||||
avatar_url = user_info['avatar_url']
|
||||
avatar_id = avatar_url.split('/')[-1]
|
||||
media_files = synapse.get_user_media(_user_id, limit=number, order=order, direction=direction).json()
|
||||
media_ids = []
|
||||
full_size = 0
|
||||
for media in media_files['media']:
|
||||
if media['media_id'] == avatar_id:
|
||||
print(f"Avatar detected! {avatar_id}")
|
||||
pass
|
||||
else:
|
||||
get_media_info(media)
|
||||
full_size += media['media_length']
|
||||
media_ids.append(media['media_id'])
|
||||
print("================================================")
|
||||
print("Number of media: {}".format(len(media_ids)))
|
||||
print("Total space usage: {}MB".format(int(full_size / (1024 * 1024))))
|
||||
return media_ids
|
||||
|
||||
|
||||
def delete_media(media_ids):
|
||||
for i, media_id in enumerate(media_ids):
|
||||
delete = synapse.delete_media_by_id(media_id)
|
||||
print(i + 1, delete.json())
|
||||
|
||||
|
||||
def get_users_list(num):
|
||||
users = []
|
||||
users_list = synapse.get_users_media_usage(num).json()
|
||||
for user in users_list['users']:
|
||||
if user['user_id'] == "@telegrambot:matrix.hirad.it":
|
||||
pass
|
||||
else:
|
||||
get_user_info(user)
|
||||
users.append(user['user_id'])
|
||||
return users
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
synapse = Synapse()
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Clean Synapse media"
|
||||
)
|
||||
|
||||
# User
|
||||
parser.add_argument("-u",
|
||||
"--user",
|
||||
metavar="USERNAME",
|
||||
help="Enter username")
|
||||
parser.add_argument("-n",
|
||||
"--number",
|
||||
type=int,
|
||||
default=100,
|
||||
metavar="NUMBER",
|
||||
help="Enter number of media to display (default: 100)")
|
||||
parser.add_argument("-s",
|
||||
"--size",
|
||||
type=int,
|
||||
default=1024,
|
||||
metavar="SIZE",
|
||||
help="Enter size limit in KB (default: 1024)")
|
||||
|
||||
# List
|
||||
parser.add_argument("-l",
|
||||
"--list",
|
||||
action="store_true",
|
||||
help="Get the list of users with highest media usage")
|
||||
list_group = parser.add_argument_group("List options")
|
||||
list_group.add_argument("-e",
|
||||
"--numbers",
|
||||
type=int,
|
||||
default=10,
|
||||
metavar="NUMBER",
|
||||
help="Enter number of users to display (default: 10)")
|
||||
parser.add_argument("-y",
|
||||
action="store_true",
|
||||
help="Run the script without asking for confirmation")
|
||||
parser.add_argument("-o",
|
||||
"--order",
|
||||
type=str,
|
||||
default="media_length",
|
||||
metavar="ORDER",
|
||||
help="Enter order by (default: media_length)[media_length|created_ts]")
|
||||
parser.add_argument("-d",
|
||||
"--dir",
|
||||
type=str,
|
||||
default="b",
|
||||
metavar="DIR",
|
||||
help="Enter direction (default: b)[f|b]")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.user:
|
||||
username = args.user
|
||||
user_id = f"@{username}:{synapse.homeserver}"
|
||||
number_of_media = args.number
|
||||
size_of_media = args.size
|
||||
medias = get_user_media(
|
||||
_user_id=user_id,
|
||||
number=number_of_media,
|
||||
size=size_of_media,
|
||||
order=args.order,
|
||||
direction=args.dir
|
||||
)
|
||||
if args.y:
|
||||
delete_media(media_ids=medias)
|
||||
else:
|
||||
confirm = input("Are you sure you want to delete the files? (y/n)")
|
||||
if confirm.lower() == 'y':
|
||||
delete_media(media_ids=medias)
|
||||
|
||||
if args.list:
|
||||
number_of_users = args.numbers
|
||||
list_of_users = get_users_list(number_of_users)
|
||||
for user in list_of_users:
|
||||
print(user)
|
||||
medias = get_user_media(_user_id=user, order=args.order, direction=args.dir)
|
||||
if args.y:
|
||||
delete_media(medias)
|
||||
else:
|
||||
confirm = input("Are you sure you want to delete the files? (y/n/c) ")
|
||||
if confirm.lower() == 'y':
|
||||
delete_media(medias)
|
||||
elif confirm.lower() == 'c':
|
||||
exit()
|
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
0
src/api/__init__.py
Normal file
0
src/api/__init__.py
Normal file
16
src/api/media_info.py
Normal file
16
src/api/media_info.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from datetime import datetime
|
||||
|
||||
|
||||
def get_media_info(media):
|
||||
media_id = media['media_id']
|
||||
media_type = media['media_type']
|
||||
media_length = media['media_length']
|
||||
media_name = media['upload_name']
|
||||
created_ts = media['created_ts']
|
||||
|
||||
media_mb_size = media_length / (1024 * 1024)
|
||||
media_size = round(media_mb_size, 2)
|
||||
|
||||
unix_ts = datetime.fromtimestamp(created_ts / 1000.0).strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
print(f"ID: {media_id}, Name: {media_name}, Type: {media_type}, Size: {media_size}MB, Created: {unix_ts}")
|
51
src/api/synapse.py
Normal file
51
src/api/synapse.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import requests
|
||||
from src.config.config_parser import Config
|
||||
|
||||
|
||||
class Synapse:
|
||||
def __init__(self):
|
||||
self.homeserver = None
|
||||
self.access_token = None
|
||||
self.header = None
|
||||
self.base_url = None
|
||||
self.initialize()
|
||||
|
||||
def initialize(self):
|
||||
config = Config()
|
||||
self.homeserver, self.access_token = config.get_config()
|
||||
self.base_url = f"https://{self.homeserver}/_synapse/admin"
|
||||
self.header = {"Authorization": f"Bearer {self.access_token}"}
|
||||
|
||||
def request(self, url, method):
|
||||
try:
|
||||
return requests.request(url=url, headers=self.header, method=method)
|
||||
except Exception as e:
|
||||
print(f"Error making request: {e}")
|
||||
return None
|
||||
|
||||
def delete_media_by_id(self, media_id):
|
||||
url = f"{self.base_url}/v1/media/{self.homeserver}/{media_id}"
|
||||
return self.request(url, "DELETE")
|
||||
|
||||
def get_users_media_usage(self, limit=100, order="media_length", direction="b"):
|
||||
url = f"{self.base_url}/v1/statistics/users/media?limit={limit}&order_by={order}&dir={direction}"
|
||||
return self.request(url, "GET")
|
||||
|
||||
def search_for_user(self, search_term, limit=10, order="media_length", direction="b"):
|
||||
url = f"{self.base_url}/v1/statistics/users/media?search_term={search_term}&order_by={order}&dir={direction}"
|
||||
return self.request(url, "GET")
|
||||
|
||||
def get_rooms_list(self, room_name=None, batch=0):
|
||||
if room_name:
|
||||
url = f"{self.base_url}/v1/rooms?search_term={room_name}&from={batch}"
|
||||
else:
|
||||
url = f"{self.base_url}/v1/rooms?from={batch}"
|
||||
return self.request(url, "GET")
|
||||
|
||||
def get_user_info(self, user_id):
|
||||
url = f"{self.base_url}/v2/users/{user_id}"
|
||||
return self.request(url, "GET")
|
||||
|
||||
def get_user_media(self, user_id, limit=100, order="media_length", direction="b"):
|
||||
url = f"{self.base_url}/v1/users/{user_id}/media?limit={limit}&order_by={order}&dir={direction}"
|
||||
return self.request(url, "GET")
|
14
src/api/user_info.py
Normal file
14
src/api/user_info.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
def get_user_info(user):
|
||||
user_id = user['user_id']
|
||||
display_name = user['displayname']
|
||||
media_count = user['media_count']
|
||||
media_length = user['media_length']
|
||||
|
||||
media_mb_size = media_length / (1024 * 1024)
|
||||
media_size = round(media_mb_size, 2)
|
||||
|
||||
output = f"Username: {display_name}, ID: {user_id}, Media Count: {media_count}, Media Size: {media_size}MB"
|
||||
print(output)
|
||||
print(len(output) * "-")
|
0
src/config/__init__.py
Normal file
0
src/config/__init__.py
Normal file
48
src/config/config_parser.py
Normal file
48
src/config/config_parser.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
import os
|
||||
from configparser import ConfigParser
|
||||
|
||||
|
||||
CONFIG_FILE_PATH = 'config.ini'
|
||||
|
||||
|
||||
class Config:
|
||||
def __init__(self):
|
||||
self.config = ConfigParser()
|
||||
self.config_file = 'config.ini'
|
||||
self.get_config()
|
||||
|
||||
def check_config_exists(self):
|
||||
if os.path.exists(self.config_file):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_config(self):
|
||||
if self.check_config_exists():
|
||||
try:
|
||||
self.config.read(self.config_file)
|
||||
homeserver = self.config.get('synapse', 'homeserver')
|
||||
access_token = self.config.get('synapse', 'access_token')
|
||||
return homeserver, access_token
|
||||
except Exception as e:
|
||||
print(f"Error reading config file: {e}")
|
||||
return None, None
|
||||
else:
|
||||
homeserver = input("Enter homeserver url: ")
|
||||
access_token = input("Enter access token: ")
|
||||
if homeserver and access_token:
|
||||
self.config['synapse'] = {
|
||||
'homeserver': homeserver,
|
||||
'access_token': access_token
|
||||
}
|
||||
with open(self.config_file, 'w') as configfile:
|
||||
self.config.write(configfile)
|
||||
|
||||
def get_excluded_users(self):
|
||||
try:
|
||||
self.config.read(self.config_file)
|
||||
excluded_users = self.config.get('options', 'excluded_users').split(',')
|
||||
return excluded_users
|
||||
except Exception as e:
|
||||
print(f"Error reading config file: {e}")
|
||||
return []
|
0
src/data/__init__.py
Normal file
0
src/data/__init__.py
Normal file
0
src/data/database.py
Normal file
0
src/data/database.py
Normal file
Loading…
Reference in a new issue