source: mailjam/mailjam/cli.py@ 23:adc5b22efd7e

Last change on this file since 23:adc5b22efd7e was 23:adc5b22efd7e, checked in by Borja Lopez <borja@…>, 12 years ago

Added the first version of the CLI client, which implements a shell-like
interface where users can interact with a mailjam server.

This first versions adds no "big" features, but contains the basis to build
a complete shell interface (including history saving support, completion,
help for commands, etc)

Added a custom configuration file (conf/mailjam-cli.conf) for the CLI
client.

Added a new mailjam.config class (CLIClientConfig) that is used by the CLI
client to load its configuration file.

Updated the package information (setup.py, MANIFEST) to include the CLI
client data.

Modified the behaviour of the XMLRPC methods registered in the *XMLRPC classes
within the daemon module. Now instead of raising exceptions directly, they
catch such exceptions, returning only a string representation of the error
to the XMLRPC client. If there is no error, a nice "ok" message is returned.

File size: 4.3 KB
Line 
1# -*- coding: utf-8 -*-
2
3"""
4The mailjam project - cli.py
5
6This file is released under the BSD license, see LICENSE for
7more information.
8
9Francisco de Borja Lopez Rio - <borja@codigo23.net>
10Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
11"""
12
13import os, cmd, xmlrpclib
14from mailjam.config import CLIClientConfig
15
16class CLIClient(cmd.Cmd):
17
18 def __init__(self, configfile=None, *args, **kwargs):
19 cmd.Cmd.__init__(self)
20 cli_config = CLIClientConfig(configfile=configfile)
21 cli_config.load()
22 self.config = cli_config.config
23 self.rpc = xmlrpclib.ServerProxy(self.config['server']['uri'])
24 self.prompt = "mailjam-cli > "
25 self.intro = "Welcome to Mailjam's CLI client - type help for a list of commands"
26 self._history = []
27
28 def do_history(self, line):
29 """
30 history
31 Show a list of recently executed commands
32
33 Alias: h
34 """
35 if not self._history:
36 print 'No history data available'
37 else:
38 for i in self._history:
39 print self._history.index(i), ' - ', i
40
41 def do_h(self, line):
42 """
43 h
44 Alias for the history command. To learn more type:
45
46 help history
47 """
48 self.do_history(line)
49
50 def do_add_mailing_list(self, line):
51 """
52 add_mailing_list [name] address
53 Add a new mailing list to the remote mailjam server. You have to
54 provide a valid email address for the mailing list to be added. If no
55 name is provided, the address itself will be used.
56
57 Alias: aml
58 """
59 if not line:
60 print 'usage: add_mailing_list [name] address'
61 else:
62 params = line.split(' ')
63 address = params.pop()
64 if not params:
65 name = address
66 else:
67 name = ' '.join(params)
68 info = {'name': name, 'address': address, 'members': {},
69 'configfile': self.config['server']['configfile']}
70 result = self.rpc.lists.add(info)
71 print result
72
73 def do_aml(self, line):
74 """
75 aml [name] address
76 Alias for the add_mailing_list command. To learn more type:
77
78 help add_mailing_list
79 """
80 self.do_add_mailing_list(line)
81
82 def do_add_mailing_list_member(self, line):
83 """
84 add_mailing_list_member member_address list_address
85 Add a new member to a given mailing list. You have to provide valid
86 email addresses for both the member and the list. The mailing list
87 must be handled by the remote mailjam server for this operation to
88 work.
89
90 Alias: amlm
91 """
92 pass
93
94 def do_show_mailing_list_members(self, line):
95 """
96 show_mailing_list_members address
97 """
98 pass
99
100 def do_EOF(self, line):
101 return True
102
103 def precmd(self, line):
104 # save the commands to the history, if it is enabled in the config file
105 if self.config['history']['enabled']:
106 self._history.append(line)
107 return line
108
109 def postloop(self):
110 # save history to a file, if it is enabled in the config file.
111 if self.config['history']['enabled']:
112 history_file_name = self.config['history']['path']
113 if '~' in history_file_name:
114 # we have to replace that with the proper home path
115 # FIXME: we should call some "sanitize" function here, to
116 # get rid of dangerous paths in the file name
117 home = os.path.expanduser("~")
118 history_file_name = history_file_name.replace('~', home)
119 if not os.path.exists(history_file_name):
120 try:
121 os.makedirs(os.path.dirname(history_file_name))
122 except OSError, e:
123 # If the dir already exists do not complain, if it is
124 # any other error, raise the exception
125 if e.errno != errno.EEXIST:
126 raise
127 history_file = open(history_file_name, 'a')
128 for i in self._history:
129 if 'EOF' not in i:
130 history_file.write(i+'\n')
131 history_file.close()
132 print 'Bye!'
133
134 def emptyline(self):
135 pass
Note: See TracBrowser for help on using the repository browser.