From a614c97d8ead5c97737e7fc13c335e76cc2a5fc9 Mon Sep 17 00:00:00 2001
From: Kentai Radiquum <kentai.waah@gmail.com>
Date: Fri, 17 Jan 2025 23:52:59 +0500
Subject: [PATCH] add command configuration via config

---
 config.yaml.example                | 11 +++++
 stickerbridge/bot_commands.py      | 26 +++++++----
 stickerbridge/chat_functions.py    |  5 ++
 stickerbridge/matrix_preview.py    | 73 +++++++++++++++++++-----------
 stickerbridge/matrix_reuploader.py | 21 +++++----
 stickerbridge/sticker_types.py     | 10 +++-
 6 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/config.yaml.example b/config.yaml.example
index 8179aef..00f0864 100644
--- a/config.yaml.example
+++ b/config.yaml.example
@@ -27,4 +27,15 @@ matrix_deviceid: "A1sbDXXX"
 
 command_prefix: "!sb"
 
+# Default Parameters Configuration of commands
+
+import:
+  set_primary: True
+  save_json: True
+
+preview:
+  space: null
+  preview_url_base: null
+  update_room: True
+
 log_level: INFO
diff --git a/stickerbridge/bot_commands.py b/stickerbridge/bot_commands.py
index a9524cf..d2ce43d 100644
--- a/stickerbridge/bot_commands.py
+++ b/stickerbridge/bot_commands.py
@@ -82,14 +82,17 @@ class Command:
             "\t\t-a  | --artist <artist> - Use this flag if you want to include sticker pack artist to json file\n"
             "\t\t-au | --artist-url <artist_url> - Use this flag if you want to add artist url to json file\n"
             "\t\t-r  | --rating <safe|questionable|explicit|s|q|e|sfw|nsfw> - Use this flag if you want add rating to json file\n"
+            "\t\tIF boolean flags are true in config, and are provided, they are applied as a False.\n"
             "preview [pack_name] - Use this to create a preview for a Telegram stickers. If pack_name is not provided, then preview is generated for a primary pack.\n"
             "\tFlags:\n"
-            "\t\t-tu | --tg-url <telegram_url|telegram_shortname> - Use this flag if you want to include stickerpack url in the last message\n"
-            "\t\t-a | --artist <artist> - Use this flag if you want to include stickerpack artist in the last message and room topic\n"
-            "\t\t-au | --artist-url <artist_url> - Use this flag if you want to add artist url in to the last message and room topic\n"
-            "\t\t-s | --space <#space:homeserver> - Use this flag if you want to include space name in the room topic\n"
-            "\t\t-pu | --preview-url <website_url> - Use this flag if you want to include stickerpack preview url in the room topic\n"
+            "\t\t-tu | --tg-url [telegram_url|telegram_shortname] - Use this flag if you want to include stickerpack url in the last message\n"
+            "\t\t-a | --artist [artist] - Use this flag if you want to include stickerpack artist in the last message and room topic\n"
+            "\t\t-au | --artist-url [artist_url] - Use this flag if you want to add artist url in to the last message and room topic\n"
+            "\t\t-s | --space [#space:homeserver] - Use this flag if you want to include space name in the room topic\n"
+            "\t\t-pu | --preview-url [website_url] - Use this flag if you want to include stickerpack preview url in the room topic\n"
             "\t\t-upd | --update-room - Use this flag if you want to update room avatar, name and topic\n"
+            "\t\tIF flags are provided, without parameters, then parameters are taken from the pack content if were provided on import or config!\n"
+            "\t\tIF boolean flags are true in config, and are provided, they are applied as a False.\n"
         )
         await send_text_to_room(self.client, self.room.room_id, text)
 
@@ -113,6 +116,7 @@ class Command:
         #       -a  | --artist <artist> - Use this flag if you want to include stickerpack artist to json file
         #       -au | --artist-url <artist_url> - Use this flag if you want to add artist url to json file
         #       -r  | --rating <safe|questionable|explicit|s|q|e|sfw|nsfw> - Use this flag if you want add rating to json file
+        #       IF boolean flags are true in config, and are provided, they are applied as a False.
         #
 
         reuploader = MatrixReuploader(self.client, self.room, exporter=self.tg_exporter)
@@ -151,12 +155,14 @@ class Command:
 
         #
         #   Flags:
-        #       -tu | --tg-url <telegram_url|telegram_shortname> - Use this flag if you want to include stickerpack url in the last message
-        #       -a | --artist <artist> - Use this flag if you want to include stickerpack artist in the last message and room topic
-        #       -au | --artist-url <artist_url> - Use this flag if you want to add artist url in to the last message and room topic
-        #       -s | --space <#space:homeserver> - Use this flag if you want to include space name in the room topic
-        #       -pu | --preview-url <website_url> - Use this flag if you want to include stickerpack preview url in the room topic
+        #       -tu | --tg-url [telegram_url|telegram_shortname] - Use this flag if you want to include stickerpack url in the last message.
+        #       -a | --artist [artist] - Use this flag if you want to include stickerpack artist in the last message and room topic
+        #       -au | --artist-url [artist_url] - Use this flag if you want to add artist url in to the last message and room topic
+        #       -s | --space [#space:homeserver] - Use this flag if you want to include space name in the room topic
+        #       -pu | --preview-url [website_url] - Use this flag if you want to include stickerpack preview url in the room topic
         #       -upd | --update-room - Use this flag if you want to update room avatar, name and topic
+        #       IF flags are provided, without parameters, then parameters are taken from the pack content if were provided on import or config!
+        #       IF boolean flags are true in config, and are provided, they are applied as a False.
 
         previewer = MatrixPreview(self.client, self.room)
         async for status in previewer.generate_stickerset_preview_to_room(pack_name, flags):
diff --git a/stickerbridge/chat_functions.py b/stickerbridge/chat_functions.py
index 98613de..2374b1f 100644
--- a/stickerbridge/chat_functions.py
+++ b/stickerbridge/chat_functions.py
@@ -66,6 +66,11 @@ async def is_stickerpack_existing(client: AsyncClient, room_id: str, pack_name:
     return not response.content == {}
 
 
+async def get_stickerpack(client: AsyncClient, room_id: str, pack_name: str):
+    response = (await client.room_get_state_event(room_id, 'im.ponies.room_emotes', pack_name))
+    return response.content
+
+
 async def upload_stickerpack(client: AsyncClient, room_id: str, stickerset: MatrixStickerset, name):
     return await client.room_put_state(room_id, 'im.ponies.room_emotes', stickerset.json(), state_key=name)
 
diff --git a/stickerbridge/matrix_preview.py b/stickerbridge/matrix_preview.py
index 307093a..f7a2204 100644
--- a/stickerbridge/matrix_preview.py
+++ b/stickerbridge/matrix_preview.py
@@ -1,20 +1,26 @@
 from nio import MatrixRoom, AsyncClient
+import yaml
+import os
 
-from chat_functions import has_permission, is_stickerpack_existing, send_sticker_to_room, update_room_image, update_room_name, update_room_topic, send_text_to_room_as_text
+from chat_functions import has_permission, is_stickerpack_existing, get_stickerpack, send_sticker_to_room, update_room_image, update_room_name, update_room_topic, send_text_to_room_as_text
 
-async def _parse_args(args: list) -> dict[str, str]:
+async def _parse_args(args: list, stickerpack) -> dict[str, str]:
+
+    if os.path.exists('config.yaml'):
+        with open("config.yaml", 'r') as config_file:
+            config_params = yaml.safe_load(config_file)
 
     parsed_args = {
-        "space": None,
+        "space": config_params['preview']['space'] or None,
         "artist" : None,
         "artist_url": None,
         "tg_url": None,
-        "preview_url": None,
-        "update_room": False
+        "preview_url": config_params['preview']['preview_url_base'] or None,
+        "update_room": config_params['preview']['update_room'] or False
     }
 
     if len(args) == 0:
-        return parsed_args
+        return parsed_args, config_params
 
     for index, arg in enumerate(args):
         if not arg.startswith("-"):
@@ -26,35 +32,47 @@ async def _parse_args(args: list) -> dict[str, str]:
             try:
                 parameter = args[index]
                 value = args[index + 1]
+                if value.startswith("-"):
+                    raise IndexError
             except IndexError:
-                continue
+                value = None
 
             if parameter in ["-tu", "--tg-url"]:
-                if not value.startswith("https://t.me/addstickers/"):
+                if value is None and stickerpack['pack'].get('pack_id', None) is not None:
+                    value = stickerpack['pack']['pack_id']
+                if value is not None and not value.startswith("https://t.me/addstickers/"):
                     value = f"https://t.me/addstickers/{value}"
                 parsed_args["tg_url"] = value
 
             elif parameter in ["-a", "--artist"]:
-                parsed_args["artist"] = value
+                if value is None and stickerpack['pack'].get('author', None) is not None and stickerpack['pack']['author'].get('name', None) is not None:
+                    value = stickerpack['pack']['author']['name']
+                if value is not None:
+                    parsed_args["artist"] = value
 
             elif parameter in ["-au", "--artist-url"]:
-                if not value.startswith("http"):
-                    continue
-                parsed_args["artist_url"] = value
+                if value is None and stickerpack['pack'].get('author', None) is not None and stickerpack['pack']['author'].get('url', None) is not None:
+                    value = stickerpack['pack']['author']['url']
+                if value is not None:
+                    if not value.startswith("http"):
+                        value = f"https://{value}"
+                    parsed_args["artist_url"] = value
 
             elif parameter in ["-s", "--space"]:
-                if not value.startswith("#") or not ":" in value:
-                    continue
+                if value is not None and (not value.startswith("#") or not ":" in value):
+                        value = None
+                        print("wrong space name format! ignoring...")
                 parsed_args["space"] = value
 
             elif parameter in ["-pu", "--preview-url"]:
-                if not value.startswith("http"):
-                    continue
+                if value is not None and not value.startswith("http"):
+                    value = None
                 parsed_args["preview_url"] = value
-        if arg in ["-upd", "--update-room"]:
-            parsed_args["update_room"] = True
 
-    return parsed_args
+        if arg in ["-upd", "--update-room"]:
+            parsed_args["update_room"] = not config_params['preview']['update_room']
+
+    return parsed_args, config_params
 
 
 class MatrixPreview:
@@ -83,18 +101,18 @@ class MatrixPreview:
             yield self.STATUS_PACK_NOT_EXISTS
             return
 
-        parsed_args = await _parse_args(flags)
+        stickerpack = await get_stickerpack(self.client, self.room.room_id, pack_name)
+        parsed_args, config_params = await _parse_args(flags, stickerpack)
 
         yield self.STATUS_UPDATING_ROOM_STATE
 
-        stickerpack = await self.client.room_get_state_event(self.room.room_id, 'im.ponies.room_emotes', pack_name)
-        first_item = dict(list(stickerpack.content["images"].items())[:1])
+        first_item = dict(list(stickerpack["images"].items())[:1])
         _first_item = first_item.popitem()
 
         topic = []
         message = []
 
-        message.append(f"Stickerpack: {stickerpack.content['pack']['display_name']}")
+        message.append(f"Stickerpack: {stickerpack['pack']['display_name']}")
 
         if parsed_args["space"]:
             topic.append(f"Space: {parsed_args['space']}")
@@ -113,17 +131,20 @@ class MatrixPreview:
         if parsed_args["tg_url"]:
             message.append(f"Telegram: {parsed_args['tg_url']}")
         if parsed_args["preview_url"]:
-            topic.append(f"Preview: {parsed_args['preview_url']}")
+            if parsed_args["preview_url"] == config_params['preview']['preview_url_base'] and stickerpack['pack'].get('pack_id', None) is not None:
+                parsed_args["preview_url"] = f"{parsed_args['preview_url']}{stickerpack['pack'].get('pack_id', None)}"
+            if parsed_args["preview_url"] != config_params['preview']['preview_url_base'] and parsed_args["preview_url"] is not None:
+                topic.append(f"Preview: {parsed_args['preview_url']}")
 
         topic = " | ".join(topic)
         message = "\n".join(message)
 
         if parsed_args["update_room"]:
             await update_room_image(self.client, self.room.room_id, _first_item[1]['url'])
-            await update_room_name(self.client, self.room.room_id, stickerpack.content["pack"]["display_name"])
+            await update_room_name(self.client, self.room.room_id, stickerpack["pack"]["display_name"])
             await update_room_topic(self.client, self.room.room_id, topic)
 
         # Sending stickers. min: 1, maximum: 5
-        for stick in list(stickerpack.content["images"].items())[:5]:
+        for stick in list(stickerpack["images"].items())[:5]:
             await send_sticker_to_room(self.client, self.room.room_id, {"body": stick[0], "url": stick[1]['url'], "info": {"mimetype":"image/png"}})
         await send_text_to_room_as_text(self.client, self.room.room_id, message)
diff --git a/stickerbridge/matrix_reuploader.py b/stickerbridge/matrix_reuploader.py
index bd33829..427d76f 100644
--- a/stickerbridge/matrix_reuploader.py
+++ b/stickerbridge/matrix_reuploader.py
@@ -1,6 +1,7 @@
 import tempfile
 import os
 import json
+import yaml
 
 from nio import MatrixRoom, AsyncClient
 
@@ -10,12 +11,16 @@ from telegram_exporter import TelegramExporter
 
 async def _parse_args(args: list) -> dict[str, str]:
 
+    if os.path.exists('config.yaml'):
+        with open("config.yaml", 'r') as config_file:
+            config_params = yaml.safe_load(config_file)
+
     parsed_args = {
-        "default": False,
-        "json": False,
-        "artist" : "",
-        "artist_url" : "",
-        "rating" : ""
+        "default": config_params['import']['set_primary'] or False,
+        "json": config_params['import']['save_json'] or False,
+        "artist" : None,
+        "artist_url" : None,
+        "rating" : None
     }
 
     if len(args) == 0:
@@ -52,9 +57,9 @@ async def _parse_args(args: list) -> dict[str, str]:
                 parsed_args["artist_url"] = value
         if arg in ["-p", "--primary", "-j", "--json"]:
             if arg in ["-p", "--primary"]:
-                parsed_args["default"] = True
+                parsed_args["default"] = not parsed_args["default"]
             if arg in ["-j", "--json"]:
-                parsed_args["json"] = True
+                parsed_args["json"] = not parsed_args["json"]
 
     return parsed_args
 
@@ -91,7 +96,7 @@ class MatrixReuploader:
 
         parsed_args = await _parse_args(args)
 
-        stickerset = MatrixStickerset(import_name)
+        stickerset = MatrixStickerset(import_name, pack_name, parsed_args["rating"], {"name": parsed_args["artist"], "url": parsed_args["artist_url"]})
         json_stickerset = MauniumStickerset(import_name, pack_name, parsed_args["rating"], {"name": parsed_args["artist"], "url": parsed_args["artist_url"]}, self.room.room_id)
         if await is_stickerpack_existing(self.client, self.room.room_id, stickerset.name()):
             yield self.STATUS_PACK_EXISTS
diff --git a/stickerbridge/sticker_types.py b/stickerbridge/sticker_types.py
index 0b5dc0d..62017fe 100644
--- a/stickerbridge/sticker_types.py
+++ b/stickerbridge/sticker_types.py
@@ -11,10 +11,13 @@ class Sticker:
 
 
 class MatrixStickerset:
-    def __init__(self, pack_name: str):
+    def __init__(self, import_name: str, pack_name: str, rating: str, author: str):
         self._content = {
             "pack": {
-                "display_name": pack_name
+                "display_name": import_name,
+                "pack_id": pack_name,
+                "rating": rating,
+                "author": author
             },
             "images": {}
         }
@@ -38,6 +41,9 @@ class MatrixStickerset:
     def name(self):
         return self._content['pack']['display_name']
 
+    def id(self):
+        return self._content['pack']['pack_id']
+
     def json(self):
         return self._content