Talking sessions are now ready.

This commit is contained in:
Davte 2018-11-26 17:32:21 +01:00
parent 328258d2af
commit 2ab0712036
2 changed files with 194 additions and 71 deletions

View File

@ -7,7 +7,7 @@ __author__ = "Davide Testa"
__email__ = "davte@libero.it" __email__ = "davte@libero.it"
__credits__ = "Marco Origlia" __credits__ = "Marco Origlia"
__license__ = "GNU General Public License v3.0" __license__ = "GNU General Public License v3.0"
__version__ = "1.4.15" __version__ = "1.4.16"
__maintainer__ = "Davide Testa" __maintainer__ = "Davide Testa"
__contact__ = "t.me/davte" __contact__ = "t.me/davte"

View File

@ -10,13 +10,21 @@ davtelepot.admin_tools.init(my_bot)
# Third party modules # Third party modules
from davteutil.utilities import ( from davteutil.utilities import (
async_wrapper, get_cleaned_text, get_user, escape_html_chars, extract, async_wrapper, Confirmator, get_cleaned_text, get_user, escape_html_chars,
line_drawing_unordered_list, make_button, make_inline_keyboard, extract, line_drawing_unordered_list, make_button, make_inline_keyboard,
remove_html_tags remove_html_tags
) )
TALK_MESSAGES = dict( TALK_MESSAGES = dict(
admin_session_ended=dict(
en=(
'Session with user {u} ended.'
),
it={
'Sessione terminata con l\'utente {u}.'
},
),
admin_warning=dict( admin_warning=dict(
en=( en=(
'You are now talking to {u}.\n' 'You are now talking to {u}.\n'
@ -29,6 +37,14 @@ TALK_MESSAGES = dict(
'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.' 'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.'
), ),
), ),
end_session=dict(
en=(
'End session?'
),
it=(
'Chiudere la sessione?'
),
),
help_text=dict( help_text=dict(
en='Press the button to search for user.', en='Press the button to search for user.',
it='Premi il pulsante per scegliere un utente.' it='Premi il pulsante per scegliere un utente.'
@ -69,6 +85,14 @@ TALK_MESSAGES = dict(
'Termina la sessione' 'Termina la sessione'
}, },
), ),
user_session_ended=dict(
en=(
'Session with admin {u} ended.'
),
it={
'Sessione terminata con l\'amministratore {u}.'
},
),
user_warning=dict( user_warning=dict(
en=( en=(
'{u}, admin of this bot, wants to talk to you.\n' '{u}, admin of this bot, wants to talk to you.\n'
@ -98,7 +122,22 @@ TALK_MESSAGES = dict(
async def _forward_to(update, bot, sender, addressee, is_admin=False): async def _forward_to(update, bot, sender, addressee, is_admin=False):
if update['text'].lower() in ['stop'] and is_admin: if update['text'].lower() in ['stop'] and is_admin:
pass # Remove custom parser to sender and addressee with bot.db as db:
admin_record = db['users'].find_one(
telegram_id=sender
)
session_record = db['talking_sessions'].find_one(
admin=admin_record['id'],
cancelled=0
)
user_record = db['users'].find_one(
id=session_record['user']
)
await end_session(
bot=bot,
user_record=user_record,
admin_record=admin_record
)
else: else:
bot.set_custom_parser( bot.set_custom_parser(
await async_wrapper( await async_wrapper(
@ -269,6 +308,109 @@ async def _talk_command(update, bot):
) )
async def start_session(bot, user_record, admin_record):
"""Start talking session between user and admin.
Register session in database, so it gets loaded before message_loop starts.
Send a notification both to admin and user, set custom parsers and return.
"""
with bot.db as db:
db['talking_sessions'].insert(
dict(
user=user_record['id'],
admin=admin_record['id'],
cancelled=0
)
)
await bot.send_message(
chat_id=user_record['telegram_id'],
text=bot.get_message(
'talk', 'user_warning',
user_record=user_record,
u=get_user(admin_record)
)
)
await bot.send_message(
chat_id=admin_record['telegram_id'],
text=bot.get_message(
'talk', 'admin_warning',
user_record=admin_record,
u=get_user(user_record)
),
reply_markup=make_inline_keyboard(
[
make_button(
bot.get_message(
'talk', 'stop',
user_record=admin_record
),
prefix='talk:///',
data=['stop', user_record['id']]
)
]
)
)
bot.set_custom_parser(
await async_wrapper(
_forward_to,
bot=bot,
sender=user_record['telegram_id'],
addressee=admin_record['telegram_id'],
is_admin=False
),
user_record['telegram_id']
)
bot.set_custom_parser(
await async_wrapper(
_forward_to,
bot=bot,
sender=admin_record['telegram_id'],
addressee=user_record['telegram_id'],
is_admin=True
),
admin_record['telegram_id']
)
return
async def end_session(bot, user_record, admin_record):
"""End talking session between user and admin.
Cancel session in database, so it will not be loaded anymore.
Send a notification both to admin and user, clear custom parsers
and return.
"""
with bot.db as db:
db['talking_sessions'].update(
dict(
admin=admin_record['id'],
cancelled=1
),
['admin']
)
await bot.send_message(
chat_id=user_record['telegram_id'],
text=bot.get_message(
'talk', 'user_session_ended',
user_record=user_record,
u=get_user(admin_record)
)
)
await bot.send_message(
chat_id=admin_record['telegram_id'],
text=bot.get_message(
'talk', 'admin_session_ended',
user_record=admin_record,
u=get_user(user_record)
),
)
for record in (admin_record, user_record, ):
telegram_id = record['telegram_id']
if telegram_id in bot.custom_parsers:
del bot.custom_parsers[telegram_id]
return
async def _talk_button(update, bot): async def _talk_button(update, bot):
telegram_id = update['from']['id'] telegram_id = update['from']['id']
command, *arguments = extract(update['data'], '///').split('|') command, *arguments = extract(update['data'], '///').split('|')
@ -287,7 +429,10 @@ async def _talk_button(update, bot):
) )
reply_markup = None reply_markup = None
elif command == 'select': elif command == 'select':
if len(arguments) < 1: if (
len(arguments) < 1
or not arguments[0].isnumeric()
):
result = "Errore!" result = "Errore!"
else: else:
with bot.db as db: with bot.db as db:
@ -297,75 +442,37 @@ async def _talk_button(update, bot):
admin_record = db['users'].find_one( admin_record = db['users'].find_one(
telegram_id=telegram_id telegram_id=telegram_id
) )
db['talking_sessions'].insert( await start_session(
dict( bot,
user=user_record['id'], user_record=user_record,
admin=admin_record['id'], admin_record=admin_record
cancelled=0
)
)
await bot.send_message(
chat_id=user_record['telegram_id'],
text=bot.get_message(
'talk', 'user_warning',
update=update,
u=get_user(admin_record)
)
)
await bot.send_message(
chat_id=admin_record['telegram_id'],
text=bot.get_message(
'talk', 'admin_warning',
update=update,
u=get_user(user_record)
),
reply_markup=make_inline_keyboard(
[
make_button(
bot.get_message(
'talk', 'stop',
update=update
),
prefix='talk:///',
data=['stop']
)
]
)
)
bot.set_custom_parser(
await async_wrapper(
_forward_to,
bot=bot,
sender=user_record['telegram_id'],
addressee=admin_record['telegram_id'],
is_admin=False
),
user_record['telegram_id']
)
bot.set_custom_parser(
await async_wrapper(
_forward_to,
bot=bot,
sender=admin_record['telegram_id'],
addressee=user_record['telegram_id'],
is_admin=True
),
admin_record['telegram_id']
) )
elif command == 'stop': elif command == 'stop':
with bot.db as db: if (
admin_record = db['users'].find_one( len(arguments) < 1
telegram_id=telegram_id or not arguments[0].isnumeric()
):
result = "Errore!"
elif not Confirmator.get('stop_bots').confirm(telegram_id):
result = bot.get_message(
'talk', 'end_session',
update=update,
) )
db['talking_sessions'].update( else:
dict( with bot.db as db:
admin=admin_record['id'], user_record = db['users'].find_one(
cancelled=1 id=int(arguments[0])
), )
['admin'] admin_record = db['users'].find_one(
telegram_id=telegram_id
)
await end_session(
bot,
user_record=user_record,
admin_record=admin_record
) )
# TODO: message which says it has stopped text = "Session ended."
# TODO: register talking session in database reply_markup = None
if text: if text:
return dict( return dict(
text=result, text=result,
@ -394,6 +501,7 @@ def init(bot):
@bot.additional_task(when='BEFORE') @bot.additional_task(when='BEFORE')
async def load_talking_sessions(): async def load_talking_sessions():
sessions = []
with bot.db as db: with bot.db as db:
for session in db.query( for session in db.query(
"""SELECT * """SELECT *
@ -401,7 +509,22 @@ def init(bot):
WHERE NOT cancelled WHERE NOT cancelled
""" """
): ):
pass # Set cutom_parser sessions.append(
dict(
user_record=db['users'].find_one(
id=session['user']
),
admin_record=db['users'].find_one(
id=session['admin']
),
)
)
for session in sessions:
await start_session(
bot=bot,
user_record=session['user_record'],
admin_record=session['admin_record']
)
@bot.command(command='/talk', aliases=[], show_in_keyboard=False, @bot.command(command='/talk', aliases=[], show_in_keyboard=False,
descr="Choose a user and forward messages to each other.", descr="Choose a user and forward messages to each other.",