Queer European MD passionate about IT
Browse Source

Config command implemented, allowing administrators to add variables to configuration files

Davte 9 months ago
parent
commit
febe5cee3f
5 changed files with 111 additions and 9 deletions
  1. 1 1
      davtelepot/__init__.py
  2. 54 1
      davtelepot/administration_tools.py
  3. 5 7
      davtelepot/cli.py
  4. 47 0
      davtelepot/messages.py
  5. 4 0
      davtelepot/utilities.py

+ 1 - 1
davtelepot/__init__.py

@@ -11,7 +11,7 @@ __author__ = "Davide Testa"
 __email__ = "davide@davte.it"
 __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
 __license__ = "GNU General Public License v3.0"
-__version__ = "2.9.1"
+__version__ = "2.9.2"
 __maintainer__ = "Davide Testa"
 __contact__ = "t.me/davte"
 

+ 54 - 1
davtelepot/administration_tools.py

@@ -29,13 +29,17 @@ from davtelepot.utilities import (
     async_wrapper, CachedPage, Confirmator, extract, get_cleaned_text,
     get_user, clean_html_string, line_drawing_unordered_list, make_button,
     make_inline_keyboard, remove_html_tags, send_part_of_text_file,
-    send_csv_file, make_lines_of_buttons
+    send_csv_file, make_lines_of_buttons, join_path
 )
 
 # Use this parameter in SQL `LIMIT x OFFSET y` clauses
 rows_number_limit = 10
 
 command_description_parser = re.compile(r'(?P<command>\w+)(\s?-\s?(?P<description>.*))?')
+variable_regex = re.compile(r"(?P<name>[a-zA-Z][\w]*)\s*=\s*"
+                            r"(?P<value>[\d.,]+|True|False|"
+                            r"'[^']*'|"
+                            r"\"[^\"]*\")")
 
 
 async def _forward_to(update,
@@ -1805,6 +1809,40 @@ async def _father_button(bot: Bot, user_record: OrderedDict,
     return result
 
 
+async def _config_command(bot: Bot, update: dict,
+                          user_record: dict, language: str):
+    text = get_cleaned_text(
+        update,
+        bot,
+        ['config']
+    )
+    if not text:
+        return bot.get_message('admin', 'config_command',
+                               'instructions',
+                               user_record=user_record,
+                               language=language)
+    match = variable_regex.match(text)
+    if not match:
+        return bot.get_message('admin', 'config_command',
+                               'invalid_input',
+                               user_record=user_record,
+                               language=language)
+    match = match.groupdict()
+    if (',' in match['value']
+            and not match['value'].startswith('\'')
+            and not match['value'].startswith('"')):
+        match['value'] = match['value'].replace(',', '.')
+    new_variable = f"{match['name']} = {match['value']}"
+    with open(join_path(bot.path, 'data', 'config.py'),
+              'a') as configuration_file:
+        configuration_file.write(f"{new_variable}\n")
+    return bot.get_message('admin', 'config_command',
+                           'success',
+                           new_variable=new_variable,
+                           user_record=user_record,
+                           language=language)
+
+
 def init(telegram_bot: Bot,
          talk_messages: dict = None,
          admin_messages: dict = None,
@@ -2019,3 +2057,18 @@ def init(telegram_bot: Bot,
                                       update=update,
                                       user_record=user_record,
                                       language=language)
+
+    @telegram_bot.command(command='/config',
+                          aliases=[],
+                          **{key: admin_messages['config_command'][key]
+                             for key in ('reply_keyboard_button',
+                                         'description',
+                                         'help_section',)
+                             },
+                          show_in_keyboard=False,
+                          authorization_level='admin')
+    async def config_command(bot, update, user_record, language):
+        return await _config_command(bot=bot,
+                                     update=update,
+                                     user_record=user_record,
+                                     language=language)

+ 5 - 7
davtelepot/cli.py

@@ -10,14 +10,10 @@ import davtelepot.administration_tools as administration_tools
 import davtelepot.helper as helper
 from davtelepot.bot import Bot
 from davtelepot.utilities import (get_cleaned_text, get_secure_key,
-                                  get_user, json_read, json_write,
+                                  get_user, join_path, json_read, json_write,
                                   line_drawing_unordered_list)
 
 
-def join_path(*args):
-    return os.path.abspath(os.path.join(*args))
-
-
 def dir_path(path):
     if os.path.isdir(path) and os.access(path, os.W_OK):
         return path
@@ -99,11 +95,13 @@ async def elevate_to_admin(bot: Bot, update: dict, user_record: dict,
 
 def allow_elevation_to_admin(telegram_bot: Bot) -> None:
     secret = get_secure_key(length=15)
+
     @telegram_bot.additional_task('BEFORE')
     async def print_secret():
         await telegram_bot.get_me()
         logging.info(f"To get administration privileges, enter code {secret} "
                      f"or click here: https://t.me/{telegram_bot.name}?start=00elevate_{secret}")
+
     @telegram_bot.command(command='/elevate', aliases=['00elevate_'], show_in_keyboard=False,
                           authorization_level='anybody')
     async def _elevate_to_admin(bot, update, user_record):
@@ -143,7 +141,7 @@ def send_single_message(telegram_bot: Bot):
               line_drawing_unordered_list(
                   list(map(lambda x: get_user(x, False),
                            records[:max_shown]))
-                  + (['...'] if len(records)>=max_shown else [])
+                  + (['...'] if len(records) >= max_shown else [])
               ),
               sep='\n')
         text = input("Select a recipient: write part of their name.\t\t")
@@ -165,7 +163,7 @@ def run_from_command_line():
     stored_arguments_file = os.path.join(arguments['path'],
                                          'cli_args.json')
     for key, value in json_read(file_=stored_arguments_file,
-                                     default={}).items():
+                                default={}).items():
         if key not in arguments or not arguments[key]:
             arguments[key] = value
     set_loggers(**{k: v

+ 47 - 0
davtelepot/messages.py

@@ -36,6 +36,53 @@ default_admin_messages = {
             'it': "annulla",
         },
     },
+    'config_command': {
+        'description': {
+            'en': "Add a variable to the configuration file",
+            'it': "Aggiungi una variabile al file di configurazione",
+        },
+        'help_section': None,
+        'instructions': {
+            'en': "<b>Config 🔧</b>\n\n"
+                  "<i>Send me a new configuration variable, for example:</i>\n"
+                  "<code>variable = 2</code>",
+            'it': "<b>Configurazione 🔧</b>\n\n"
+                  "<i>Mandami una variabile da aggiungere al file di "
+                  "configurazione, per esempio:</i>\n"
+                  "<code>variabile = 2</code>",
+        },
+        'invalid_input': {
+            'en': "<b>❌ Invalid input 🔧</b>\n\n"
+                  "<i>Send me a new configuration variable, for example:</i>\n"
+                  "<code>int_var = 2\n"
+                  "str_var = 'test'\n"
+                  "bool_var = False\n"
+                  "float_var = 3.5</code>",
+            'it': "<b>❌ Configurazione scorretta 🔧</b>\n\n"
+                  "<i>Mandami una variabile da aggiungere al file di "
+                  "configurazione, per esempio:</i>\n"
+                  "<code>var_int = 2\n"
+                  "var_str = 'test'\n"
+                  "var_bool = False\n"
+                  "var_float = 3.5</code>",
+        },
+        'reply_keyboard_button': {
+            'en': "Config 🔧",
+            'it': "Configurazione 🔧",
+        },
+        'success': {
+            'en': "<b>✔️ Configuration updated 🔧</b>\n\n"
+                  "The following variable has been added to the configuration "
+                  "file:\n"
+                  "<code>{new_variable}</code>\n\n"
+                  "/restart to apply",
+            'it': "<b>✔️ Configurazione aggiornata 🔧</b>\n\n"
+                  "La seguente variabile è stata aggiunta al file di "
+                  "configurazione:\n"
+                  "<code>{new_variable}</code>\n\n"
+                  "Per rendere effettive le modifiche fai /restart",
+        },
+    },
     'confirm': {
         'en': "🔄 Click again to confirm",
         'it': "🔄 Clicka di nuovo per confermare",

+ 4 - 0
davtelepot/utilities.py

@@ -1738,3 +1738,7 @@ async def aio_subprocess_shell(command: str) -> Tuple[str, str]:
             )
         )
     return stdout, stderr
+
+
+def join_path(*args):
+    return os.path.abspath(os.path.join(*args))