# HG changeset patch # User Paul Boddie # Date 1506892190 -7200 # Node ID 4af5f81f530108c99b05f5b84fa8fab13d24dbe0 # Parent c3c9e3dd3213662279e11fc770c152208dca494c Changed the initialisation of resources in the agent programs to immediately obtain configuration defaults, if necessary. Introduced support for disabling free/busy publishing by using None as the publishing directory. Added more documentation for the system configuration options. diff -r c3c9e3dd3213 -r 4af5f81f5301 docs/wiki/Configuration --- a/docs/wiki/Configuration Sun Oct 01 22:32:11 2017 +0200 +++ b/docs/wiki/Configuration Sun Oct 01 23:09:50 2017 +0200 @@ -90,8 +90,10 @@ * `config.txt` provides the configuration of the software itself * User preferences reside as files in separate user-specific directories -These files are by default installed into the `/etc/imip-agent` directory -and they can be changed in that location once the system is installed. +The `config` files are by default installed into the `/etc/imip-agent` directory +and they can be changed in that location once the system is installed. User +preferences can be configured directly in the filesystem or can be edited in the +[[../CalendarManager|management interface]] by each user. === System-Level and Tool Configuration === @@ -138,6 +140,71 @@ and file permissions), service-level settings (e-mail address and Web site choices), and default policies for users of the software. +The syntax of `config.txt` is the same as Python, but only simple value +assignments can be defined, along with comments. Strings must appear within +quotes and thus numbers, boolean values and strings can be expressed. The +following examples employ necessary quoting. + +{{{#!table +'''Setting''' || '''Example Value''' || '''Description''' +== +`MESSAGE_SENDER` || `"calendar@example.com"` +|| The address from which messages sent by the agent originate +== +`LOCAL_PREFIX` || `"local"` +|| The prefix employed by the mail system to identify local recipients +== +`OUTGOING_PREFIX` || `"people-outgoing"` +|| The prefix employed by the mail system to identify local recipients +.. being the senders of outgoing messages +== +`STORE_TYPE` || `"file"` +|| The store and journal type +== +`STORE_DIR` || `"/var/lib/imip-agent/store"` +|| The location of the stored calendar information, defined in a form +.. appropriate to the selected `STORE_TYPE` +== +`PUBLISH_DIR` || `"/var/www/imip-agent/static"` +|| The location of published static free/busy information, which if +.. given as `None` will cause any such publishing to be disabled +== +`PREFERENCES_DIR` || `"/var/lib/imip-agent/preferences"` +|| The location of user preferences information +== +`JOURNAL_DIR` || `"/var/lib/imip-agent/journal"` +|| The location of quota-related journal information +== +`DEFAULT_PERMISSIONS` || `0660` +|| The octal permission flags for files accessed by Web users and the +.. agent programs +== +`DEFAULT_DIR_PERMISSIONS` || `02770` +|| The octal permission flags for directories, intended to preserve +.. group ownership +== +`LOCALE_DIR` || `"/usr/share/locale"` +|| The location of message translations on the system +== +`TRANS_DOMAIN` || `"imip-agent"` +|| The name of the application used to find message translations +== +`MANAGER_INTERFACE` || `True` +|| Advertise the Web management interface in mails sent to calendar users +== +`MANAGER_PATH` || `"/imip-manager"` +|| The server-relative path at which the management interface is deployed +.. in the Web server environment +== +`MANAGER_URL` || `None` +|| The full URL of the manager application excluding the above path, +.. used to provide specific hostname details instead of those deduced from +.. the environment (when set to None) +== +`MANAGER_URL_SCHEME` || `"http://"` +|| The protocol scheme used if constructing URLs +}}} + === User Preferences === Although the software configuration in `config.txt` provides default policies, diff -r c3c9e3dd3213 -r 4af5f81f5301 imiptools/__init__.py --- a/imiptools/__init__.py Sun Oct 01 22:32:11 2017 +0200 +++ b/imiptools/__init__.py Sun Oct 01 23:09:50 2017 +0200 @@ -67,7 +67,7 @@ return get_store(self.store_type, self.store_dir) def get_publisher(self): - return self.publishing_dir and get_publisher(self.publishing_dir) or None + return get_publisher(self.publishing_dir) def get_journal(self): return get_journal(self.store_type, self.journal_dir) @@ -117,6 +117,10 @@ # Process the message for each recipient. + if self.debug: + print >>sys.stderr, "Recipients..." + print >>sys.stderr, ", ".join(users) + for user in users: Recipient(user, messenger, store, publisher, journal, preferences_dir, self.handlers, self.outgoing_only, @@ -201,16 +205,33 @@ getvalue = lambda value, default=None: value and value[0] or default self.messenger = Messenger(lmtp_socket=getvalue(lmtp), local_smtp=local_smtp, sender=getvalue(senders)) + + # Obtain arguments or configured defaults. + self.store_type = getvalue(store_type, settings["STORE_TYPE"]) - self.store_dir = getvalue(store_dir) - self.publishing_dir = getvalue(publishing_dir) - self.preferences_dir = getvalue(preferences_dir) - self.journal_dir = getvalue(journal_dir) + self.store_dir = getvalue(store_dir, settings["STORE_DIR"]) + self.journal_dir = getvalue(journal_dir, settings["JOURNAL_DIR"]) + self.preferences_dir = getvalue(preferences_dir, settings["PREFERENCES_DIR"]) + self.publishing_dir = getvalue(publishing_dir, settings["PUBLISH_DIR"]) + + # Show configuration and exit if requested. + + if "--show-config" in args: + print """\ +Store type: %s +Store directory: %s +Journal directory: %s +Preferences directory: %s +Publishing directory: %s""" % ( + self.store_type, self.store_dir, self.journal_dir, + self.preferences_dir, self.publishing_dir) + return # If debug mode is set, extend the line length for convenience. if self.debug: settings["CALENDAR_LINE_LENGTH"] = 1000 + print >>sys.stderr, "Store type", self.store_type, "at", self.store_dir # Process the input. @@ -230,7 +251,8 @@ Usage: %s [ -o ... ] [-s ... ] [ -l | -L ] \\ [ -T ] [ -P ] \\ - [ -p ] [ -j ] [ -d ] + [ -p ] [ -j ] \\ + [ -d ] [ --show-config ] Address options: @@ -249,7 +271,7 @@ (Where a program needs to deliver messages, one of the above options must be specified.) -Configuration options: +Configuration options (overriding configured defaults): -j Indicates the location of quota-related journal information -P Indicates the location of published free/busy resources @@ -261,8 +283,15 @@ Output options: -d Run in debug mode, producing informative output describing the behaviour - of the program + of the program, displaying responses on standard output instead of sending + messages + +Diagnostic options: + +--show-config Show the configuration with the specified options and exit + without performing any actions """ % os.path.split(sys.argv[0])[-1] + elif "-d" in args: self.process_args(args, sys.stdin) else: @@ -273,16 +302,23 @@ except Exception, exc: if "-v" in args: raise + + # Obtain the exception origin. + type, value, tb = sys.exc_info() while tb.tb_next: tb = tb.tb_next f = tb.tb_frame co = f and f.f_code filename = co and co.co_filename + print >>sys.stderr, "Exception %s at %d in %s" % (exc, tb.tb_lineno, filename) + #import traceback #traceback.print_exc(file=open("/tmp/mail.log", "a")) + sys.exit(EX_TEMPFAIL) + sys.exit(0) class Recipient(Client): @@ -313,10 +349,15 @@ may be constructed according to individual preferences. """ - handlers = dict([(name, cls(senders, self.user and get_address(self.user), - self.messenger, self.store, self.publisher, - self.journal, self.preferences_dir)) - for name, cls in self.handlers]) + handlers = {} + + # Instantiate handlers for the supported methods. + + for name, cls in self.handlers: + handlers[name] = cls(senders, self.user and get_address(self.user), + self.messenger, self.store, self.publisher, + self.journal, self.preferences_dir) + handled = False # Check for participating recipients. Non-participating recipients will @@ -334,6 +375,9 @@ if part.get_content_type() in itip_content_types and \ part.get_param("method"): + if self.debug: + print >>sys.stderr, "Handle method %s..." % part.get_param("method") + handle_itip_part(part, handlers) handled = True diff -r c3c9e3dd3213 -r 4af5f81f5301 imiptools/config.txt --- a/imiptools/config.txt Sun Oct 01 22:32:11 2017 +0200 +++ b/imiptools/config.txt Sun Oct 01 23:09:50 2017 +0200 @@ -19,6 +19,7 @@ STORE_DIR = "/var/lib/imip-agent/store" # The location of published static free/busy information. +# Set to None to disable publishing completely. PUBLISH_DIR = "/var/www/imip-agent/static" @@ -92,6 +93,7 @@ SHARING_DEFAULT = "no" # Are free/busy details published on the Web by default? +# Set PUBLISH_DIR to a suitable directory for publishing to function. PUBLISHING_DEFAULT = "no" diff -r c3c9e3dd3213 -r 4af5f81f5301 imiptools/stores/__init__.py --- a/imiptools/stores/__init__.py Sun Oct 01 22:32:11 2017 +0200 +++ b/imiptools/stores/__init__.py Sun Oct 01 23:09:50 2017 +0200 @@ -24,12 +24,33 @@ # Access functions. def get_store(store_type, store_dir): + + """ + Return a store for the given 'store_type' and 'store_dir'. If 'store_dir' + is given as a null or false value then the configured default is used. + """ + return stores[store_type].Store(store_dir) def get_publisher(publishing_dir): - return stores["file"].Publisher(publishing_dir) + + """ + Return a publishing resource employing 'publishing_dir'. If the specified + directory is given as a null or false value, None is returned. Thus, all + free/busy publishing can be disabled by changing the configuration to use + None as the directory. + """ + + return publishing_dir and stores["file"].Publisher(publishing_dir) or None def get_journal(store_type, journal_dir): + + """ + Return a journal for the given 'store_type' and 'journal_dir'. If + 'journal_dir' is given as a null or false value then the configured default + is used. + """ + return stores[store_type].Journal(journal_dir) # vim: tabstop=4 expandtab shiftwidth=4