diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index de41dfd8..2c78cb29 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -56,6 +56,11 @@ jobs: pip install -r requirements.txt pip install pyinstaller==5.5 + - name: Install configurator dependencies + working-directory: backend/configurator + run: | + pip install -r requirements.txt + - name: Install fastapi dependencies working-directory: backend/fastapi run: | @@ -79,6 +84,10 @@ jobs: working-directory: backend/windows-runner run: pyinstaller --onefile --name dcef windows-runner.py --icon=icon.ico + - name: Build configurator executable with pyinstaller + working-directory: backend/configurator + run: pyinstaller --onefile --name configurator main.py + - name: Install http-server working-directory: backend/http-server run: npm install @@ -101,6 +110,7 @@ jobs: cp backend\mongodb\msvcp140.dll build\dcef\backend\mongodb\msvcp140.dll cp backend\http-server\http-server.exe build\dcef\backend\http-server\http-server.exe cp backend\windows-runner\dist\dcef.exe build\dcef.exe + cp backend\configurator\dist\configurator.exe build\configurator.exe Copy-Item -Path release\exports\* -Destination build\exports -Recurse cp release\registry_tweaks\change_260_character_path_limit_to_32767.reg build\registry_tweaks\change_260_character_path_limit_to_32767.reg cp release\registry_tweaks\restore_260_character_path_limit.reg build\registry_tweaks\restore_260_character_path_limit.reg diff --git a/Dockerfile b/Dockerfile index f54f06b0..ad99cd38 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,7 @@ COPY /backend/nginx/conf/nginx-docker.conf /dcef/backend/nginx/conf/nginx-docker COPY --from=build /app/build/ ./frontend/ COPY backend/preprocess/ ./backend/preprocess/ COPY backend/fastapi/ ./backend/fastapi/ +COPY backend/configurator/main.py ./configurator.py COPY backend/docker/run_container.sh ./run_container.sh RUN chmod 777 /dcef/run_container.sh EXPOSE 21011 diff --git a/Dockerfile.rpi4b b/Dockerfile.rpi4b index aee352d8..118d4a0a 100644 --- a/Dockerfile.rpi4b +++ b/Dockerfile.rpi4b @@ -45,6 +45,7 @@ COPY /backend/nginx/conf/nginx-docker.conf /dcef/backend/nginx/conf/nginx-docker COPY --from=build /app/build/ ./frontend/ COPY backend/preprocess/ ./backend/preprocess/ COPY backend/fastapi/ ./backend/fastapi/ +COPY backend/configurator/main.py ./configurator.py COPY backend/docker/run_container.sh ./run_container.sh RUN chmod 777 /dcef/run_container.sh EXPOSE 21011 diff --git a/backend/configurator/main.py b/backend/configurator/main.py new file mode 100644 index 00000000..49f97a17 --- /dev/null +++ b/backend/configurator/main.py @@ -0,0 +1,188 @@ +import pymongo + +URI = "mongodb://127.0.0.1:27017" +client = pymongo.MongoClient(URI) +db = client["dcef"] +collection_guilds = db["guilds"] +collection_config = db["config"] + +def pad_id(id): + if id == None: + return None + return str(id).zfill(24) + +def get_guilds(): + return collection_guilds.find().sort("msg_count", pymongo.DESCENDING) + +def get_whitelisted_guild_ids(): + whitelisted_guild_ids = collection_config.find_one({"key": "whitelisted_guild_ids"})["value"] + whitelisted_guild_ids = [pad_id(id) for id in whitelisted_guild_ids] + return whitelisted_guild_ids + +def get_blacklisted_user_ids(): + blacklisted_user_ids = collection_config.find_one({"key": "blacklisted_user_ids"})["value"] + blacklisted_user_ids = [pad_id(id) for id in blacklisted_user_ids] + return blacklisted_user_ids + +def set_whitelisted_guild_ids(whitelisted_guild_ids): + print("Applying whitelisted guild ids...") + collection_config.update_one({"key": "whitelisted_guild_ids"}, {"$set": {"value": whitelisted_guild_ids}}) + if len(whitelisted_guild_ids) == 0: + print("all guilds are now whitelisted") + else: + print(f"whitelisted {len(whitelisted_guild_ids)} guilds") + print("") + +def set_blacklisted_user_ids(blacklisted_user_ids): + print("Applying blacklisted user ids...") + collection_config.update_one({"key": "blacklisted_user_ids"}, {"$set": {"value": blacklisted_user_ids}}) + if len(blacklisted_user_ids) == 0: + print("no users are blacklisted") + else: + print(f"{len(blacklisted_user_ids)} users are now blacklisted") + +def resolve_user_id(user_id): + user_id = pad_id(user_id) + guilds = list(get_guilds()) + for guild in guilds: + authors_collection_name = f"g{pad_id(guild['_id'])}_authors" + authors_collection = db[authors_collection_name] + + user = authors_collection.find_one({"_id": user_id}) + if user != None: + return user['names'] + user['nicknames'] + +def menu_whitelist(): + guilds = list(get_guilds()) + whitelisted_ids = get_whitelisted_guild_ids() + whitelisted_ids = [id for id in whitelisted_ids if id in [guild['_id'] for guild in guilds]] # remove invalid ids + while True: + print("choice | action | whitelist status | guild_name") + print("-------|------------------|------------------|--------------------------") + print("CTRL+C | back | - | - ") + for i, guild in enumerate(guilds): + is_whitelisted = guild['_id'] in whitelisted_ids + whitelisted_status = "" + if is_whitelisted: + whitelisted_status = "whitelisted " + elif len(whitelisted_ids) == 0: + whitelisted_status = "not-configured " + else: + whitelisted_status = "not-whitelisted" + print(f"{str(i).ljust(6)} | toggle whitelist | {whitelisted_status} | {guild['name']}") + try: + index = int(input(f"Index of guild to toggle whitelist status (0-{len(guilds)-1}): ")) + guild_id = guilds[index]['_id'] + if guild_id in whitelisted_ids: + whitelisted_ids.remove(guild_id) + else: + whitelisted_ids.append(guild_id) + + set_whitelisted_guild_ids(whitelisted_ids) + + except ValueError: + print("Invalid input") + break + + except KeyboardInterrupt: + print("\nExiting...") + break + +def menu_add_user_to_blacklist(blacklisted_user_ids): + while True: + try: + print("\n(right click profile picture in DCEF -> Copy author ID)") + user_id = input("User id: ") + user_id = pad_id(user_id) + user_names = resolve_user_id(user_id) + if user_names == None: + print("User not found") + continue + + print("Found user:", ', '.join(user_names)) + if user_id in blacklisted_user_ids: + print("This user is already blacklisted") + continue + + blacklisted_user_ids.append(user_id) + set_blacklisted_user_ids(blacklisted_user_ids) + break + + except KeyboardInterrupt: + print("\nExiting...") + break + + return blacklisted_user_ids + + +def menu_blacklist_users(): + blacklisted_user_ids = list(get_blacklisted_user_ids()) + + while True: + print("") + print("choice | action | user_id | also_known_as") + print("-------|-----------------------|--------------------------|--------------------------") + print("CTRL+C | back | - | - ") + print("0 | blacklist new user | - | - ") + for i, user_id in enumerate(blacklisted_user_ids): + print(f"{str(i+1).ljust(5)} | remove from blacklist | {user_id} | {', '.join(resolve_user_id(user_id))}") + try: + index = int(input(f"Choice (0-{len(blacklisted_user_ids)}): ")) + if index == 0: + blacklisted_user_ids = menu_add_user_to_blacklist(blacklisted_user_ids) + else: + user_id = blacklisted_user_ids[index-1] + blacklisted_user_ids.remove(user_id) + set_blacklisted_user_ids(blacklisted_user_ids) + continue + + + except ValueError: + print("Invalid input") + break + + except KeyboardInterrupt: + print("\nExiting...") + break + +def main(): + print("\n") + print("############################") + print("# DCEF server configurator #") + print("############################") + print("(all changes are applied immediately)\n") + + print("Connecting to mongo database (DCEF needs to be running)...") + try: + client.server_info() + print("Database is online\n") + except: + print("Database is offline. Run DCEF and try again\n") + return + + + + while True: + print("choice | action") + print("-------|-----------------") + print("CTRL+C | exit ") + print("0 | Whitelist server") + print("1 | Blacklist user ") + print("") + try: + choice = int(input("Choice (0-1): ")) + if choice == 0: + menu_whitelist() + elif choice == 1: + menu_blacklist_users() + else: + print("Invalid choice") + except ValueError: + print("Invalid choice") + except KeyboardInterrupt: + print("\nExiting...") + break + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/backend/configurator/requirements.txt b/backend/configurator/requirements.txt new file mode 100644 index 00000000..a9b45b1f --- /dev/null +++ b/backend/configurator/requirements.txt @@ -0,0 +1 @@ +pymongo==4.3.3 \ No newline at end of file diff --git a/backend/fastapi/helpers.py b/backend/fastapi/helpers.py index 025d1dd9..e12cbaf0 100644 --- a/backend/fastapi/helpers.py +++ b/backend/fastapi/helpers.py @@ -10,7 +10,6 @@ def pad_id(id): URI = "mongodb://127.0.0.1:27017" client = pymongo.MongoClient(URI) db = client["dcef"] -collection_messages = db["messages"] collection_guilds = db["guilds"] collection_config = db["config"]