Fix mailman lists command to not output trailing blanks and handle long list ids.
[mailman.git] / src / mailman / commands / cli_inject.py
blob5ee1734dcd4c6cc902800ca69c274ccca2d5b4b2
1 # Copyright (C) 2009-2023 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <https://www.gnu.org/licenses/>.
18 """The `mailman inject` subcommand."""
20 import sys
21 import click
23 from mailman.app.inject import inject_text
24 from mailman.config import config
25 from mailman.core.i18n import _
26 from mailman.interfaces.command import ICLISubCommand
27 from mailman.interfaces.listmanager import IListManager
28 from mailman.utilities.options import I18nCommand
29 from public import public
30 from zope.component import getUtility
31 from zope.interface import implementer
34 def show_queues(ctx, param, value):
35 if value:
36 print('Available queues:')
37 for switchboard in sorted(config.switchboards):
38 print(' ', switchboard)
39 sys.exit(0)
40 # Returning None tells click to process the rest of the command line.
43 @click.command(
44 cls=I18nCommand,
45 help=_("Inject a message from a file into a mailing list's queue."))
46 @click.option(
47 '--queue', '-q',
48 help=_("""\
49 The name of the queue to inject the message to. QUEUE must be one of the
50 directories inside the queue directory. If omitted, the incoming queue is
51 used."""))
52 @click.option(
53 '--show', '-s',
54 is_flag=True, default=False, is_eager=True, expose_value=False,
55 callback=show_queues,
56 help=_('Show a list of all available queue names and exit.'))
57 @click.option(
58 '--filename', '-f', 'message_file',
59 default='-', type=click.File(encoding='utf-8'),
60 help=_("""\
61 Name of file containing the message to inject. If not given, or
62 '-' (without the quotes) standard input is used."""))
63 @click.option(
64 '--metadata', '-m', 'keywords',
65 multiple=True, metavar='KEY=VALUE',
66 help=_("""\
67 Additional metadata key/value pairs to add to the message metadata
68 dictionary. Use the format key=value. Multiple -m options are
69 allowed."""))
70 @click.argument('listspec')
71 @click.pass_context
72 def inject(ctx, queue, message_file, keywords, listspec):
73 mlist = getUtility(IListManager).get(listspec)
74 if mlist is None:
75 ctx.fail(_('No such list: ${listspec}'))
76 queue_name = ('in' if queue is None else queue)
77 switchboard = config.switchboards.get(queue_name)
78 if switchboard is None:
79 ctx.fail(_('No such queue: ${queue}'))
80 try:
81 message_text = message_file.read()
82 except KeyboardInterrupt:
83 print('Interrupted')
84 sys.exit(1)
85 kws = {}
86 for keyvalue in keywords:
87 key, equals, value = keyvalue.partition('=')
88 kws[key] = value
89 inject_text(mlist, message_text, switchboard=queue, **kws)
92 @public
93 @implementer(ICLISubCommand)
94 class Inject:
95 name = 'inject'
96 command = inject