diff --git a/metabot/botconf.py b/metabot/botconf.py
index e0e9020..469dd51 100644
--- a/metabot/botconf.py
+++ b/metabot/botconf.py
@@ -27,7 +27,7 @@ def __init__(self, confdir=None): # pylint: disable=too-many-branches
if fname.endswith('.yaml'):
self[fname[:-len('.yaml')]] = yamlutil.load(os.path.join(confdir, fname))
- # Schema update: Remove after 2019-03-26.
+ # Schema update: Remove after 2019-03-26 (https://github.com/nmlorg/metabot/issues/18).
if not self['bots']:
fname = os.path.join(confdir, 'multibot.json')
data = jsonutil.load(fname)
@@ -35,7 +35,7 @@ def __init__(self, confdir=None): # pylint: disable=too-many-branches
self['bots'] = data
logging.info('Converted %s to %s.', fname, os.path.join(confdir, 'bots.yaml'))
- # Schema update: Remove after 2019-04-05.
+ # Schema update: Remove after 2019-04-05 (https://github.com/nmlorg/metabot/issues/18).
for botconf in self['bots'].values():
for groupid, groupconf in botconf['moderator'].items():
groupid = int(groupid)
@@ -43,7 +43,7 @@ def __init__(self, confdir=None): # pylint: disable=too-many-branches
if k in groupconf:
self['groups'][groupid][k] = groupconf[k]
- # Schema update: Remove after 2019-06-12.
+ # Schema update: Remove after 2019-06-12 (https://github.com/nmlorg/metabot/issues/37).
for botconf in self['bots'].values():
if botconf.get('telegram'):
for modname in list(botconf):
@@ -51,6 +51,16 @@ def __init__(self, confdir=None): # pylint: disable=too-many-branches
botconf['issue37'][modname] = botconf[modname]
botconf.pop(modname)
+ # Schema update: Remove after 2019-08-13 (https://github.com/nmlorg/metabot/issues/41).
+ for botconf in self['bots'].values():
+ for command, message in botconf['issue37']['echo'].items():
+ if not isinstance(message, dict):
+ botconf['issue37']['echo'][command] = {
+ 'text': message,
+ 'paginate': True,
+ 'private': '\n' in message,
+ }
+
self._fnames = set(self)
@contextlib.contextmanager
diff --git a/metabot/modules/echo.py b/metabot/modules/echo.py
index b157114..6451035 100644
--- a/metabot/modules/echo.py
+++ b/metabot/modules/echo.py
@@ -2,9 +2,12 @@
from __future__ import absolute_import, division, print_function, unicode_literals
+from metabot.util import adminui
+
def modhelp(unused_ctx, modconf, sections): # pylint: disable=missing-docstring
- for command, message in modconf.items():
+ for command, data in modconf.items():
+ message = data['text'].replace('\n', ' ')
if len(message) > 30:
message = message[:29] + '\u2026'
sections['commands'].add('/%s \u2013 "%s"' % (command, message))
@@ -17,55 +20,47 @@ def moddispatch(ctx, msg, modconf): # pylint: disable=missing-docstring
return False
-def echo(ctx, msg, message): # pylint: disable=missing-docstring
- lines = [line for line in message.splitlines() if line.strip()]
- page = ctx.text.isdigit() and int(ctx.text) or 1
- for line in lines[:page]:
- msg.add('%s', line)
- if page < len(lines):
- ctx.private = True
- msg.button('More (%i/%i)' % (page, len(lines)), '/%s %i' % (ctx.command, page + 1))
+def echo(ctx, msg, data): # pylint: disable=missing-docstring
+ ctx.private = data.get('private')
+ if not data.get('paginate'):
+ msg.add(data['text'])
+ else:
+ lines = [line for line in data['text'].splitlines() if line.strip()]
+ page = ctx.text.isdigit() and int(ctx.text) or 1
+ for line in lines[:page]:
+ msg.add('%s', line)
+ if page < len(lines):
+ msg.button('More (%i/%i)' % (page, len(lines)), '/%s %i' % (ctx.command, page + 1))
def admin(ctx, msg, modconf):
"""Handle /admin BOTNAME echo."""
- command, message = ctx.split(2)
+ command, field, message = ctx.split(3)
command = command.lower()
- if ctx.document:
- message = 'document:%s' % ctx.document
- elif ctx.photo:
- message = 'photo:%s' % ctx.photo
- elif ctx.sticker:
- message = 'sticker:%s' % ctx.sticker
-
- if command and message:
- if message == 'remove':
- if command not in modconf:
- msg.add('/%s is not echoing anything.', command)
- else:
- msg.add('Removed /%s (%s
).', command, modconf[command])
- modconf.pop(command)
- command = message = None
- else:
- if command in modconf:
- msg.add('Changed /%s from %s
to %s
.', command,
- modconf[command], message)
- else:
- msg.add('/%s now echoes %s
.', command, message)
- modconf[command] = message
- command = message = None
-
if not command:
msg.action = 'Choose a command'
msg.add(
"Type the name of a command to add (like rules
\u2014don't include a slash "
- 'at the beginning!), or select an existing echo to remove.')
- for command, message in sorted(modconf.items()):
- msg.button('/%s (%s)' % (command, message), '%s remove' % command)
+ 'at the beginning!), or select an existing echo.')
+ for command, data in sorted(modconf.items()):
+ msg.button('/%s (%s)' % (command, data['text'].replace('\n', ' ')), command)
return
msg.path(command)
- msg.action = 'Type the message for /' + command
- msg.add('Type the text you want me to send in response to /%s
:', command)
+
+ if ctx.document:
+ message = 'document:%s' % ctx.document
+ elif ctx.photo:
+ message = 'photo:%s' % ctx.photo
+ elif ctx.sticker:
+ message = 'sticker:%s' % ctx.sticker
+
+ fields = (
+ ('text', adminui.freeform,
+ 'The message, sticker, or image to send in response to /%s.' % command),
+ ('paginate', adminui.bool, 'For multiline messages, display just one line at a time?'),
+ ('private', adminui.bool, 'Send the message in group chats, or just in private?'),
+ )
+ return adminui.fields(ctx, msg, modconf[command], fields, field, message)
diff --git a/metabot/modules/test_echo.py b/metabot/modules/test_echo.py
index 0e2d35e..0e80e12 100644
--- a/metabot/modules/test_echo.py
+++ b/metabot/modules/test_echo.py
@@ -20,19 +20,37 @@ def test_echo(conversation): # pylint: disable=redefined-outer-name
assert conversation.message('/myecho') == ''
- conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['myecho'] = (
- 'These are the rules: Have fun!')
+ conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['myecho'] = {
+ 'text': 'These are the rules: Have fun!',
+ }
assert conversation.message('/myecho') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
These are the rules: Have fun!
"""
- conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['about'] = (
- 'First line.\n'
- 'Second line.\n'
- ' \n'
- 'Last line.')
+ conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['about'] = {
+ 'text': ('First line.\n'
+ 'Second line.\n'
+ ' \n'
+ 'Last line.'),
+ }
+
+ assert conversation.message('/about') == """\
+[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
+First line.
+Second line.
+
+Last line.
+"""
+
+ conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['about'] = {
+ 'text': ('First line.\n'
+ 'Second line.\n'
+ ' \n'
+ 'Last line.'),
+ 'paginate': True,
+ }
assert conversation.message('/about') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
@@ -76,10 +94,12 @@ def test_echo(conversation): # pylint: disable=redefined-outer-name
def test_help(conversation): # pylint: disable=redefined-outer-name
"""Test /help."""
- conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['rules1'] = (
- 'These are the rules: Have fun!')
- conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['rules2'] = (
- 'These are the rules: Have fun!!')
+ conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['rules1'] = {
+ 'text': 'These are the rules: Have fun!',
+ }
+ conversation.multibot.conf['bots']['modulestestbot']['issue37']['echo']['rules2'] = {
+ 'text': 'These are the rules: Have fun!!',
+ }
assert conversation.message('/help', user_id=2000) == """\
[chat_id=2000 disable_web_page_preview=True parse_mode=HTML]
@@ -98,56 +118,56 @@ def test_admin(conversation): # pylint: disable=redefined-outer-name
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
Bot Admin \u203a modulestestbot \u203a echo: Choose a command
-Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo to remove.
+Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo.
[Back | /admin modulestestbot]
"""
assert conversation.message('EchoTest') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
-Bot Admin \u203a modulestestbot \u203a echo \u203a echotest: Type the message for /echotest
-
-Type the text you want me to send in response to /echotest
:
+Bot Admin \u203a modulestestbot \u203a echo \u203a echotest: Choose a field
+[text \u2022 The message, sticker, or image to send in response to /echotest. | /admin modulestestbot echo echotest text]
+[paginate \u2022 For multiline messages, display just one line at a time? | /admin modulestestbot echo echotest paginate]
+[private \u2022 Send the message in group chats, or just in private? | /admin modulestestbot echo echotest private]
[Back | /admin modulestestbot echo]
"""
- assert conversation.message('my message') == """\
+ assert conversation.message('text') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
-Bot Admin \u203a modulestestbot \u203a echo: Choose a command
+Bot Admin \u203a modulestestbot \u203a echo \u203a echotest \u203a text: Type a new value for text
-/echotest now echoes my message
.
+The message, sticker, or image to send in response to /echotest.
-Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo to remove.
-[/echotest (my message) | /admin modulestestbot echo echotest remove]
-[Back | /admin modulestestbot]
+Type your new value, or type "off" to disable/reset to default.
+[Back | /admin modulestestbot echo echotest]
"""
- assert conversation.message('/admin modulestestbot echo echotest new message') == """\
+ assert conversation.message('my message') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
-Bot Admin \u203a modulestestbot \u203a echo: Choose a command
-
-Changed /echotest from my message
to new message
.
+Bot Admin \u203a modulestestbot \u203a echo \u203a echotest: Choose a field
-Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo to remove.
-[/echotest (new message) | /admin modulestestbot echo echotest remove]
-[Back | /admin modulestestbot]
+Set text
to my message
.
+[text \u2022 The message, sticker, or image to send in response to /echotest. | /admin modulestestbot echo echotest text]
+[paginate \u2022 For multiline messages, display just one line at a time? | /admin modulestestbot echo echotest paginate]
+[private \u2022 Send the message in group chats, or just in private? | /admin modulestestbot echo echotest private]
+[Back | /admin modulestestbot echo]
"""
- assert conversation.message('/admin modulestestbot echo echotest remove') == """\
+ assert conversation.message('/admin modulestestbot echo echotest text new message') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
-Bot Admin \u203a modulestestbot \u203a echo: Choose a command
+Bot Admin \u203a modulestestbot \u203a echo \u203a echotest: Choose a field
-Removed /echotest (new message
).
-
-Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo to remove.
-[Back | /admin modulestestbot]
+Changed text
from my message
to new message
.
+[text \u2022 The message, sticker, or image to send in response to /echotest. | /admin modulestestbot echo echotest text]
+[paginate \u2022 For multiline messages, display just one line at a time? | /admin modulestestbot echo echotest paginate]
+[private \u2022 Send the message in group chats, or just in private? | /admin modulestestbot echo echotest private]
+[Back | /admin modulestestbot echo]
"""
- assert conversation.message('/admin modulestestbot echo bogus remove') == """\
+ assert conversation.message('/admin modulestestbot echo') == """\
[chat_id=1000 disable_web_page_preview=True parse_mode=HTML]
Bot Admin \u203a modulestestbot \u203a echo: Choose a command
-/bogus is not echoing anything.
-
-Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo to remove.
+Type the name of a command to add (like rules
\u2014don't include a slash at the beginning!), or select an existing echo.
+[/echotest (new message) | /admin modulestestbot echo echotest]
[Back | /admin modulestestbot]
"""
diff --git a/metabot/util/adminui.py b/metabot/util/adminui.py
index 644cf48..686b5f1 100644
--- a/metabot/util/adminui.py
+++ b/metabot/util/adminui.py
@@ -7,6 +7,13 @@
import pytz
+def bool(unused_ctx, msg, subconf, field, unused_desc, unused_text): # pylint: disable=too-many-arguments,redefined-builtin
+ """Configure a toggle-able setting."""
+
+ subconf[field] = not subconf[field]
+ msg.add('Set %s
to %s
.', field, subconf[field])
+
+
def calendars(ctx, msg, subconf, field, desc, text): # pylint: disable=too-many-arguments
"""Configure a selection of calendars."""
diff --git a/setup.py b/setup.py
index 9eb6f0e..8ddcc09 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
setuptools.setup(
name='metabot',
- version='0.1.0.2',
+ version='0.1.0.3',
author='Daniel Reed',
author_email='nmlorg@gmail.com',
description='Modularized, multi-account bot.',