Notify new versions to admins

This commit is contained in:
Davte 2020-04-24 00:51:21 +02:00
parent 04699d0dd7
commit 6340b4d658
3 changed files with 239 additions and 159 deletions

View File

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

View File

@ -779,7 +779,8 @@ def get_maintenance_exception_criterion(bot, allowed_command):
return criterion return criterion
async def _version_command(bot, update, user_record): async def get_version():
"""Get last commit hash and davtelepot version."""
try: try:
_subprocess = await asyncio.create_subprocess_exec( _subprocess = await asyncio.create_subprocess_exec(
'git', 'rev-parse', 'HEAD', 'git', 'rev-parse', 'HEAD',
@ -788,9 +789,16 @@ async def _version_command(bot, update, user_record):
) )
stdout, _ = await _subprocess.communicate() stdout, _ = await _subprocess.communicate()
last_commit = stdout.decode().strip() last_commit = stdout.decode().strip()
davtelepot_version = davtelepot.__version__
except Exception as e: except Exception as e:
return f"{e}" last_commit = f"{e}"
if last_commit.startswith("fatal: not a git repository"):
last_commit = "-"
davtelepot_version = davtelepot.__version__
return last_commit, davtelepot_version
async def _version_command(bot, update, user_record):
last_commit, davtelepot_version = await get_version()
return bot.get_message( return bot.get_message(
'admin', 'version_command', 'result', 'admin', 'version_command', 'result',
last_commit=last_commit, last_commit=last_commit,
@ -799,6 +807,54 @@ async def _version_command(bot, update, user_record):
) )
async def notify_new_version(bot):
"""Notify `bot` administrators about new versions.
Notify admins when last commit and/or davtelepot version change.
"""
last_commit, davtelepot_version = await get_version()
old_record = bot.db['version_history'].find_one(
order_by=['-id']
)
if old_record is None:
old_record = dict(
updated_at=datetime.datetime.min,
last_commit=None,
davtelepot_version=None
)
if (
old_record['last_commit'] != last_commit
or old_record['davtelepot_version'] != davtelepot_version
):
new_record = dict(
updated_at=datetime.datetime.now(),
last_commit=last_commit,
davtelepot_version=davtelepot_version
)
bot.db['version_history'].insert(
new_record
)
for admin in bot.db['users'].find(privileges=[1, 2]):
await bot.send_message(
chat_id=admin['telegram_id'],
disable_notification=True,
text='\n\n'.join(
bot.get_message(
'admin', 'new_version', field,
old_record=old_record,
new_record=new_record,
user_record=admin
)
for field in filter(
lambda x: (x not in old_record
or old_record[x] != new_record[x]),
('title', 'last_commit', 'davtelepot_version')
)
)
)
return
def init(telegram_bot, talk_messages=None, admin_messages=None): def init(telegram_bot, talk_messages=None, admin_messages=None):
"""Assign parsers, commands, buttons and queries to given `bot`.""" """Assign parsers, commands, buttons and queries to given `bot`."""
if talk_messages is None: if talk_messages is None:
@ -994,3 +1050,7 @@ def init(telegram_bot, talk_messages=None, admin_messages=None):
return await _version_command(bot=bot, return await _version_command(bot=bot,
update=update, update=update,
user_record=user_record) user_record=user_record)
@telegram_bot.additional_task(when='BEFORE', bot=telegram_bot)
async def notify_version(bot):
return await notify_new_version(bot=bot)

View File

@ -1,70 +1,6 @@
"""Default messages for bot functions.""" """Default messages for bot functions."""
default_admin_messages = { default_admin_messages = {
'talk_command': {
'description': {
'en': "Choose a user and forward messages to each other",
'it': "Scegli un utente e il bot farà da tramite inoltrando a "
"ognuno i messaggi dell'altro finché non terminerai la "
"sessione"
}
},
'restart_command': {
'description': {
'en': "Restart bots",
'it': "Riavvia i bot"
},
'restart_scheduled_message': {
'en': "Bots are being restarted, after pulling from repository.",
'it': "I bot verranno riavviati in pochi secondi, caricando "
"prima le eventuali modifiche al codice."
},
'restart_completed_message': {
'en': "<i>Restart was successful.</i>",
'it': "<i>Restart avvenuto con successo.</i>"
}
},
'stop_command': {
'description': {
'en': "Stop bots",
'it': "Ferma i bot"
},
'text': {
'en': "Are you sure you want to stop all bots?\n"
"To make them start again you will have to ssh-log "
"in server.\n\n"
"To restart the bots remotely use the /restart command "
"instead (before starting over, a <code>git pull</code> "
"is performed).",
'it': "Sei sicuro di voler fermare i bot?\n"
"Per farli ripartire dovrai accedere al server.\n\n"
"Per far ripartire i bot da remoto usa invece il comando "
"/restart (prima di ripartire farò un "
"<code>git pull</code>)."
}
},
'stop_button': {
'stop_text': {
'en': "Stop bots",
'it': "Ferma i bot"
},
'cancel': {
'en': "Cancel",
'it': "Annulla"
},
'confirm': {
'en': "Do you really want to stop all bots?",
'it': "Vuoi davvero fermare tutti i bot?"
},
'stopping': {
'en': "Stopping bots...",
'it': "Arresto in corso..."
},
'cancelled': {
'en': "Operation was cancelled",
'it': "Operazione annullata"
}
},
'db_command': { 'db_command': {
'description': { 'description': {
'en': "Ask for bot database via Telegram", 'en': "Ask for bot database via Telegram",
@ -87,92 +23,6 @@ default_admin_messages = {
'it': "Database inviato." 'it': "Database inviato."
} }
}, },
'query_command': {
'description': {
'en': "Receive the result of a SQL query performed on bot "
"database",
'it': "Ricevi il risultato di una query SQL sul database del bot"
},
'help': {
'en': "Write a SQL query to be run on bot database.\n\n"
"<b>Example</b>\n"
"<code>/query SELECT * FROM users WHERE 0</code>",
'it': "Invia una query SQL da eseguire sul database del bot.\n\n"
"<b>Esempio</b>\n"
"<code>/query SELECT * FROM users WHERE 0</code>"
},
'no_iterable': {
'en': "No result to show was returned",
'it': "La query non ha restituito risultati da mostrare"
},
'exception': {
'en': "The query threw this error:",
'it': "La query ha dato questo errore:"
},
'result': {
'en': "Query result",
'it': "Risultato della query"
}
},
'select_command': {
'description': {
'en': "Receive the result of a SELECT query performed on bot "
"database",
'it': "Ricevi il risultato di una query SQL di tipo SELECT "
"sul database del bot"
}
},
'query_button': {
'error': {
'en': "Error!",
'it': "Errore!"
},
'file_name': {
'en': "Query result.csv",
'it': "Risultato della query.csv"
},
'empty_file': {
'en': "No result to show.",
'it': "Nessun risultato da mostrare."
}
},
'log_command': {
'description': {
'en': "Receive bot log file, if set",
'it': "Ricevi il file di log del bot, se impostato"
},
'no_log': {
'en': "Sorry but no log file is set.\n"
"To set it, use `bot.set_log_file_name` instance method or "
"`Bot.set_class_log_file_name` class method.",
'it': "Spiacente ma il file di log non è stato impostato.\n"
"Per impostarlo, usa il metodo d'istanza "
"`bot.set_log_file_name` o il metodo di classe"
"`Bot.set_class_log_file_name`."
},
'sending_failure': {
'en': "Sending log file failed!\n\n"
"<b>Error:</b>\n"
"<code>{e}</code>",
'it': "Inviio del messaggio di log fallito!\n\n"
"<b>Errore:</b>\n"
"<code>{e}</code>"
},
'here_is_log_file': {
'en': "Here is the complete log file.",
'it': "Ecco il file di log completo."
},
'log_file_first_lines': {
'en': "Here are the first {lines} lines of the log file.",
'it': "Ecco le prime {lines} righe del file di log."
},
'log_file_last_lines': {
'en': "Here are the last {lines} lines of the log file.\n"
"Newer lines are at the top of the file.",
'it': "Ecco le ultime {lines} righe del file di log.\n"
"L'ordine è cronologico, con i messaggi nuovi in alto."
}
},
'errors_command': { 'errors_command': {
'description': { 'description': {
'en': "Receive bot error log file, if set", 'en': "Receive bot error log file, if set",
@ -216,6 +66,43 @@ default_admin_messages = {
"L'ordine è cronologico, con i messaggi nuovi in alto." "L'ordine è cronologico, con i messaggi nuovi in alto."
} }
}, },
'log_command': {
'description': {
'en': "Receive bot log file, if set",
'it': "Ricevi il file di log del bot, se impostato"
},
'no_log': {
'en': "Sorry but no log file is set.\n"
"To set it, use `bot.set_log_file_name` instance method or "
"`Bot.set_class_log_file_name` class method.",
'it': "Spiacente ma il file di log non è stato impostato.\n"
"Per impostarlo, usa il metodo d'istanza "
"`bot.set_log_file_name` o il metodo di classe"
"`Bot.set_class_log_file_name`."
},
'sending_failure': {
'en': "Sending log file failed!\n\n"
"<b>Error:</b>\n"
"<code>{e}</code>",
'it': "Inviio del messaggio di log fallito!\n\n"
"<b>Errore:</b>\n"
"<code>{e}</code>"
},
'here_is_log_file': {
'en': "Here is the complete log file.",
'it': "Ecco il file di log completo."
},
'log_file_first_lines': {
'en': "Here are the first {lines} lines of the log file.",
'it': "Ecco le prime {lines} righe del file di log."
},
'log_file_last_lines': {
'en': "Here are the last {lines} lines of the log file.\n"
"Newer lines are at the top of the file.",
'it': "Ecco le ultime {lines} righe del file di log.\n"
"L'ordine è cronologico, con i messaggi nuovi in alto."
}
},
'maintenance_command': { 'maintenance_command': {
'description': { 'description': {
'en': "Put the bot under maintenance", 'en': "Put the bot under maintenance",
@ -236,6 +123,139 @@ default_admin_messages = {
'it': "<i>Manutenzione terminata!</i>" 'it': "<i>Manutenzione terminata!</i>"
} }
}, },
'new_version': {
'title': {
'en': "🔔 New version detected! 📰",
'it': "🔔 Rilevata nuova versione! 📰",
},
'last_commit': {
'en': "Old commit: <code>{old_record[last_commit]}</code>\n"
"New commit: <code>{new_record[last_commit]}</code>",
'it': "Vecchio commit: <code>{old_record[last_commit]}</code>\n"
"Nuovo commit: <code>{new_record[last_commit]}</code>",
},
'davtelepot_version': {
'en': "davtelepot version: "
"<code>{old_record[davtelepot_version]}</code> —> "
"<code>{new_record[davtelepot_version]}</code>",
'it': "Versione di davtelepot: "
"<code>{old_record[davtelepot_version]}</code> —> "
"<code>{new_record[davtelepot_version]}</code>",
},
},
'query_button': {
'error': {
'en': "Error!",
'it': "Errore!",
},
'file_name': {
'en': "Query result.csv",
'it': "Risultato della query.csv",
},
'empty_file': {
'en': "No result to show.",
'it': "Nessun risultato da mostrare.",
}
},
'query_command': {
'description': {
'en': "Receive the result of a SQL query performed on bot "
"database",
'it': "Ricevi il risultato di una query SQL sul database del bot"
},
'help': {
'en': "Write a SQL query to be run on bot database.\n\n"
"<b>Example</b>\n"
"<code>/query SELECT * FROM users WHERE 0</code>",
'it': "Invia una query SQL da eseguire sul database del bot.\n\n"
"<b>Esempio</b>\n"
"<code>/query SELECT * FROM users WHERE 0</code>"
},
'no_iterable': {
'en': "No result to show was returned",
'it': "La query non ha restituito risultati da mostrare"
},
'exception': {
'en': "The query threw this error:",
'it': "La query ha dato questo errore:"
},
'result': {
'en': "Query result",
'it': "Risultato della query"
}
},
'restart_command': {
'description': {
'en': "Restart bots",
'it': "Riavvia i bot"
},
'restart_scheduled_message': {
'en': "Bots are being restarted, after pulling from repository.",
'it': "I bot verranno riavviati in pochi secondi, caricando "
"prima le eventuali modifiche al codice."
},
'restart_completed_message': {
'en': "<i>Restart was successful.</i>",
'it': "<i>Restart avvenuto con successo.</i>"
}
},
'select_command': {
'description': {
'en': "Receive the result of a SELECT query performed on bot "
"database",
'it': "Ricevi il risultato di una query SQL di tipo SELECT "
"sul database del bot"
}
},
'stop_button': {
'stop_text': {
'en': "Stop bots",
'it': "Ferma i bot"
},
'cancel': {
'en': "Cancel",
'it': "Annulla"
},
'confirm': {
'en': "Do you really want to stop all bots?",
'it': "Vuoi davvero fermare tutti i bot?"
},
'stopping': {
'en': "Stopping bots...",
'it': "Arresto in corso..."
},
'cancelled': {
'en': "Operation was cancelled",
'it': "Operazione annullata"
}
},
'stop_command': {
'description': {
'en': "Stop bots",
'it': "Ferma i bot"
},
'text': {
'en': "Are you sure you want to stop all bots?\n"
"To make them start again you will have to ssh-log "
"in server.\n\n"
"To restart the bots remotely use the /restart command "
"instead (before starting over, a <code>git pull</code> "
"is performed).",
'it': "Sei sicuro di voler fermare i bot?\n"
"Per farli ripartire dovrai accedere al server.\n\n"
"Per far ripartire i bot da remoto usa invece il comando "
"/restart (prima di ripartire farò un "
"<code>git pull</code>)."
}
},
'talk_command': {
'description': {
'en': "Choose a user and forward messages to each other",
'it': "Scegli un utente e il bot farà da tramite inoltrando a "
"ognuno i messaggi dell'altro finché non terminerai la "
"sessione"
}
},
'version_command': { 'version_command': {
'reply_keyboard_button': { 'reply_keyboard_button': {
'en': "Version #️⃣", 'en': "Version #️⃣",
@ -247,12 +267,12 @@ default_admin_messages = {
}, },
'help_section': None, 'help_section': None,
'result': { 'result': {
'en': "Last commit: {last_commit}\n" 'en': "Last commit: <code>{last_commit}</code>\n\n"
"davtelepot version: {davtelepot_version}", "davtelepot version: <code>{davtelepot_version}</code>",
'it': "Ultimo commit: {last_commit}\n" 'it': "Ultimo commit: <code>{last_commit}</code>\n\n"
"Versione di davtelepot: {davtelepot_version}", "Versione di davtelepot: <code>{davtelepot_version}</code>",
}, },
} },
} }
default_authorization_denied_message = { default_authorization_denied_message = {