1========================== 2Operating on mailing lists 3========================== 4 5The ``shell`` (alias: ``withlist``) command is a pretty powerful way to 6operate on mailing lists from the command line. This command allows you to 7interact with a list at a Python prompt, or process one or more mailing lists 8through custom made Python functions. 9 10 11Getting detailed help 12===================== 13 14Because ``shell`` is so complex, you might want to read the detailed help. 15:: 16 17 >>> command = cli('mailman.commands.cli_withlist.shell') 18 19 >>> command('mailman shell --details') 20 This script provides you with a general framework for interacting with a 21 mailing list. 22 ... 23 24 25Running a function 26================== 27 28By putting a Python function somewhere on your ``sys.path``, you can have 29``shell`` call that function on a given mailing list. 30 31 >>> import os, sys 32 >>> old_path = sys.path[:] 33 >>> sys.path.insert(0, config.VAR_DIR) 34 35.. cleanup 36 >>> ignore = cleanups.callback(setattr, sys, 'path', old_path) 37 38The function takes at least a single argument, the mailing list. 39:: 40 41 >>> with open(os.path.join(config.VAR_DIR, 'showme.py'), 'w') as fp: 42 ... print("""\ 43 ... def showme(mlist): 44 ... print("The list's name is", mlist.fqdn_listname) 45 ... 46 ... def displayname(mlist): 47 ... print("The list's display name is", mlist.display_name) 48 ... 49 ... def changeme(mlist, display_name): 50 ... mlist.display_name = display_name 51 ... """, file=fp) 52 53If the name of the function is the same as the module, then you only need to 54name the function once. 55 56 >>> mlist = create_list('ant@example.com') 57 >>> command('mailman shell -l ant@example.com --run showme') 58 The list's name is ant@example.com 59 60The function's name can also be different than the modules name. In that 61case, just give the full module path name to the function you want to call. 62 63 >>> command('mailman shell -l ant@example.com --run showme.displayname') 64 The list's display name is Ant 65 66 67Passing arguments 68================= 69 70Your function can also accept an arbitrary number of arguments. Every command 71line argument after the callable name is passed as a positional argument to 72the function. For example, to change the mailing list's display name, you can 73do this:: 74 75 >>> command('mailman shell -l ant@example.com --run showme.changeme ANT!') 76 >>> print(mlist.display_name) 77 ANT! 78 79 80Multiple lists 81============== 82 83You can run a command over more than one list by using a regular expression in 84the ``listname`` argument. To indicate a regular expression is used, the 85string must start with a caret. 86:: 87 88 >>> mlist_2 = create_list('badger@example.com') 89 >>> mlist_3 = create_list('badboys@example.com') 90 91 >>> command('mailman shell --run showme.displayname -l ^.*example.com') 92 The list's display name is ANT! 93 The list's display name is Badboys 94 The list's display name is Badger 95 96 >>> command('mailman shell --run showme.displayname -l ^bad.*') 97 The list's display name is Badboys 98 The list's display name is Badger 99 100 >>> command('mailman shell --run showme.displayname -l ^foo') 101 102 103Interactive use 104=============== 105 106You can also get an interactive prompt which allows you to inspect a live 107Mailman system directly. Through the ``mailman.cfg`` file, you can set the 108prompt and banner, and you can choose between the standard Python REPL_ or 109IPython. 110 111If the `GNU readline`_ library is available, it will be enabled automatically, 112giving you command line editing and other features. You can also set the 113``[shell]history_file`` variable in the ``mailman.cfg`` file and when the 114normal Python REPL is used, your interactive commands will be written to and 115read from this file. 116 117Note that the ``$PYTHONSTARTUP`` environment variable will also be honored if 118set, and any file named by this variable will be read at start up time. It's 119common practice to *also* enable GNU readline history in a ``$PYTHONSTARTUP`` 120file and if you do this, be aware that it will interact badly with 121``[shell]history_file``, causing your history to be written twice. To disable 122this when using the interactive ``shell`` command, do something like:: 123 124 $ PYTHONSTARTUP= mailman shell 125 126to temporarily unset the environment variable. 127 128 129IPython 130------- 131 132You can use IPython_ as the interactive shell by setting the 133``[shell]use_ipython`` variables in your `mailman.cfg` file to ``yes``. 134IPython must be installed and available on your system 135 136When using IPython, the ``[shell]history_file`` is not used. 137 138 139.. _IPython: http://ipython.org/ 140.. _REPL: https://en.wikipedia.org/wiki/REPL 141.. _`GNU readline`: https://docs.python.org/3/library/readline.html 142