1.1 --- a/docs/wiki/Configuration Sun Oct 01 22:32:11 2017 +0200
1.2 +++ b/docs/wiki/Configuration Sun Oct 01 23:09:50 2017 +0200
1.3 @@ -90,8 +90,10 @@
1.4 * `config.txt` provides the configuration of the software itself
1.5 * User preferences reside as files in separate user-specific directories
1.6
1.7 -These files are by default installed into the `/etc/imip-agent` directory
1.8 -and they can be changed in that location once the system is installed.
1.9 +The `config` files are by default installed into the `/etc/imip-agent` directory
1.10 +and they can be changed in that location once the system is installed. User
1.11 +preferences can be configured directly in the filesystem or can be edited in the
1.12 +[[../CalendarManager|management interface]] by each user.
1.13
1.14 === System-Level and Tool Configuration ===
1.15
1.16 @@ -138,6 +140,71 @@
1.17 and file permissions), service-level settings (e-mail address and Web site
1.18 choices), and default policies for users of the software.
1.19
1.20 +The syntax of `config.txt` is the same as Python, but only simple value
1.21 +assignments can be defined, along with comments. Strings must appear within
1.22 +quotes and thus numbers, boolean values and strings can be expressed. The
1.23 +following examples employ necessary quoting.
1.24 +
1.25 +{{{#!table
1.26 +'''Setting''' || '''Example Value''' || '''Description'''
1.27 +==
1.28 +`MESSAGE_SENDER` || `"calendar@example.com"`
1.29 +|| The address from which messages sent by the agent originate
1.30 +==
1.31 +`LOCAL_PREFIX` || `"local"`
1.32 +|| The prefix employed by the mail system to identify local recipients
1.33 +==
1.34 +`OUTGOING_PREFIX` || `"people-outgoing"`
1.35 +|| The prefix employed by the mail system to identify local recipients
1.36 +.. being the senders of outgoing messages
1.37 +==
1.38 +`STORE_TYPE` || `"file"`
1.39 +|| The store and journal type
1.40 +==
1.41 +`STORE_DIR` || `"/var/lib/imip-agent/store"`
1.42 +|| The location of the stored calendar information, defined in a form
1.43 +.. appropriate to the selected `STORE_TYPE`
1.44 +==
1.45 +`PUBLISH_DIR` || `"/var/www/imip-agent/static"`
1.46 +|| The location of published static free/busy information, which if
1.47 +.. given as `None` will cause any such publishing to be disabled
1.48 +==
1.49 +`PREFERENCES_DIR` || `"/var/lib/imip-agent/preferences"`
1.50 +|| The location of user preferences information
1.51 +==
1.52 +`JOURNAL_DIR` || `"/var/lib/imip-agent/journal"`
1.53 +|| The location of quota-related journal information
1.54 +==
1.55 +`DEFAULT_PERMISSIONS` || `0660`
1.56 +|| The octal permission flags for files accessed by Web users and the
1.57 +.. agent programs
1.58 +==
1.59 +`DEFAULT_DIR_PERMISSIONS` || `02770`
1.60 +|| The octal permission flags for directories, intended to preserve
1.61 +.. group ownership
1.62 +==
1.63 +`LOCALE_DIR` || `"/usr/share/locale"`
1.64 +|| The location of message translations on the system
1.65 +==
1.66 +`TRANS_DOMAIN` || `"imip-agent"`
1.67 +|| The name of the application used to find message translations
1.68 +==
1.69 +`MANAGER_INTERFACE` || `True`
1.70 +|| Advertise the Web management interface in mails sent to calendar users
1.71 +==
1.72 +`MANAGER_PATH` || `"/imip-manager"`
1.73 +|| The server-relative path at which the management interface is deployed
1.74 +.. in the Web server environment
1.75 +==
1.76 +`MANAGER_URL` || `None`
1.77 +|| The full URL of the manager application excluding the above path,
1.78 +.. used to provide specific hostname details instead of those deduced from
1.79 +.. the environment (when set to None)
1.80 +==
1.81 +`MANAGER_URL_SCHEME` || `"http://"`
1.82 +|| The protocol scheme used if constructing URLs
1.83 +}}}
1.84 +
1.85 === User Preferences ===
1.86
1.87 Although the software configuration in `config.txt` provides default policies,
2.1 --- a/imiptools/__init__.py Sun Oct 01 22:32:11 2017 +0200
2.2 +++ b/imiptools/__init__.py Sun Oct 01 23:09:50 2017 +0200
2.3 @@ -67,7 +67,7 @@
2.4 return get_store(self.store_type, self.store_dir)
2.5
2.6 def get_publisher(self):
2.7 - return self.publishing_dir and get_publisher(self.publishing_dir) or None
2.8 + return get_publisher(self.publishing_dir)
2.9
2.10 def get_journal(self):
2.11 return get_journal(self.store_type, self.journal_dir)
2.12 @@ -117,6 +117,10 @@
2.13
2.14 # Process the message for each recipient.
2.15
2.16 + if self.debug:
2.17 + print >>sys.stderr, "Recipients..."
2.18 + print >>sys.stderr, ", ".join(users)
2.19 +
2.20 for user in users:
2.21 Recipient(user, messenger, store, publisher, journal,
2.22 preferences_dir, self.handlers, self.outgoing_only,
2.23 @@ -201,16 +205,33 @@
2.24 getvalue = lambda value, default=None: value and value[0] or default
2.25
2.26 self.messenger = Messenger(lmtp_socket=getvalue(lmtp), local_smtp=local_smtp, sender=getvalue(senders))
2.27 +
2.28 + # Obtain arguments or configured defaults.
2.29 +
2.30 self.store_type = getvalue(store_type, settings["STORE_TYPE"])
2.31 - self.store_dir = getvalue(store_dir)
2.32 - self.publishing_dir = getvalue(publishing_dir)
2.33 - self.preferences_dir = getvalue(preferences_dir)
2.34 - self.journal_dir = getvalue(journal_dir)
2.35 + self.store_dir = getvalue(store_dir, settings["STORE_DIR"])
2.36 + self.journal_dir = getvalue(journal_dir, settings["JOURNAL_DIR"])
2.37 + self.preferences_dir = getvalue(preferences_dir, settings["PREFERENCES_DIR"])
2.38 + self.publishing_dir = getvalue(publishing_dir, settings["PUBLISH_DIR"])
2.39 +
2.40 + # Show configuration and exit if requested.
2.41 +
2.42 + if "--show-config" in args:
2.43 + print """\
2.44 +Store type: %s
2.45 +Store directory: %s
2.46 +Journal directory: %s
2.47 +Preferences directory: %s
2.48 +Publishing directory: %s""" % (
2.49 + self.store_type, self.store_dir, self.journal_dir,
2.50 + self.preferences_dir, self.publishing_dir)
2.51 + return
2.52
2.53 # If debug mode is set, extend the line length for convenience.
2.54
2.55 if self.debug:
2.56 settings["CALENDAR_LINE_LENGTH"] = 1000
2.57 + print >>sys.stderr, "Store type", self.store_type, "at", self.store_dir
2.58
2.59 # Process the input.
2.60
2.61 @@ -230,7 +251,8 @@
2.62 Usage: %s [ -o <recipient> ... ] [-s <sender> ... ] [ -l <socket> | -L ] \\
2.63 [ -T <store type ] \\
2.64 [ -S <store directory> ] [ -P <publishing directory> ] \\
2.65 - [ -p <preferences directory> ] [ -j <journal directory> ] [ -d ]
2.66 + [ -p <preferences directory> ] [ -j <journal directory> ] \\
2.67 + [ -d ] [ --show-config ]
2.68
2.69 Address options:
2.70
2.71 @@ -249,7 +271,7 @@
2.72 (Where a program needs to deliver messages, one of the above options must be
2.73 specified.)
2.74
2.75 -Configuration options:
2.76 +Configuration options (overriding configured defaults):
2.77
2.78 -j Indicates the location of quota-related journal information
2.79 -P Indicates the location of published free/busy resources
2.80 @@ -261,8 +283,15 @@
2.81 Output options:
2.82
2.83 -d Run in debug mode, producing informative output describing the behaviour
2.84 - of the program
2.85 + of the program, displaying responses on standard output instead of sending
2.86 + messages
2.87 +
2.88 +Diagnostic options:
2.89 +
2.90 +--show-config Show the configuration with the specified options and exit
2.91 + without performing any actions
2.92 """ % os.path.split(sys.argv[0])[-1]
2.93 +
2.94 elif "-d" in args:
2.95 self.process_args(args, sys.stdin)
2.96 else:
2.97 @@ -273,16 +302,23 @@
2.98 except Exception, exc:
2.99 if "-v" in args:
2.100 raise
2.101 +
2.102 + # Obtain the exception origin.
2.103 +
2.104 type, value, tb = sys.exc_info()
2.105 while tb.tb_next:
2.106 tb = tb.tb_next
2.107 f = tb.tb_frame
2.108 co = f and f.f_code
2.109 filename = co and co.co_filename
2.110 +
2.111 print >>sys.stderr, "Exception %s at %d in %s" % (exc, tb.tb_lineno, filename)
2.112 +
2.113 #import traceback
2.114 #traceback.print_exc(file=open("/tmp/mail.log", "a"))
2.115 +
2.116 sys.exit(EX_TEMPFAIL)
2.117 +
2.118 sys.exit(0)
2.119
2.120 class Recipient(Client):
2.121 @@ -313,10 +349,15 @@
2.122 may be constructed according to individual preferences.
2.123 """
2.124
2.125 - handlers = dict([(name, cls(senders, self.user and get_address(self.user),
2.126 - self.messenger, self.store, self.publisher,
2.127 - self.journal, self.preferences_dir))
2.128 - for name, cls in self.handlers])
2.129 + handlers = {}
2.130 +
2.131 + # Instantiate handlers for the supported methods.
2.132 +
2.133 + for name, cls in self.handlers:
2.134 + handlers[name] = cls(senders, self.user and get_address(self.user),
2.135 + self.messenger, self.store, self.publisher,
2.136 + self.journal, self.preferences_dir)
2.137 +
2.138 handled = False
2.139
2.140 # Check for participating recipients. Non-participating recipients will
2.141 @@ -334,6 +375,9 @@
2.142 if part.get_content_type() in itip_content_types and \
2.143 part.get_param("method"):
2.144
2.145 + if self.debug:
2.146 + print >>sys.stderr, "Handle method %s..." % part.get_param("method")
2.147 +
2.148 handle_itip_part(part, handlers)
2.149 handled = True
2.150