imip-agent

Changeset

1210:7fe3be7f0ead
2017-01-30 Paul Boddie raw files shortlog changelog graph Changed the config module to load and interpret the configuration file content, exposing the settings as a dictionary instead of as module attributes.
imiptools/config.py (file) imiptools/config.txt (file) imiptools/content.py (file) imiptools/filesys.py (file) imiptools/handlers/__init__.py (file) imiptools/i18n.py (file) imiptools/mail.py (file) imiptools/profile.py (file) imiptools/stores/database/postgresql.py (file) imiptools/stores/file.py (file) tools/install.sh (file)
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/imiptools/config.py	Mon Jan 30 23:28:11 2017 +0100
     1.3 @@ -0,0 +1,73 @@
     1.4 +#!/usr/bin/env python
     1.5 +
     1.6 +"""
     1.7 +Configuration management.
     1.8 +
     1.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
    1.10 +
    1.11 +This program is free software; you can redistribute it and/or modify it under
    1.12 +the terms of the GNU General Public License as published by the Free Software
    1.13 +Foundation; either version 3 of the License, or (at your option) any later
    1.14 +version.
    1.15 +
    1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
    1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.18 +FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    1.19 +details.
    1.20 +
    1.21 +You should have received a copy of the GNU General Public License along with
    1.22 +this program.  If not, see <http://www.gnu.org/licenses/>.
    1.23 +"""
    1.24 +
    1.25 +from compiler import parseFile
    1.26 +from os.path import isfile, join, split
    1.27 +from compiler.ast import Assign, AssName, Const, Discard, Module, Name, Stmt
    1.28 +
    1.29 +config_path = [".", "/etc/imip-agent", split(__file__)[0]]
    1.30 +
    1.31 +builtins = {
    1.32 +    "False" : False,
    1.33 +    "None" : None,
    1.34 +    "True" : True,
    1.35 +    }
    1.36 +
    1.37 +def get_config(filename="config.txt", path=config_path):
    1.38 +
    1.39 +    "Obtain the configuration from 'filename', searching 'path' for the file."
    1.40 +
    1.41 +    for dirname in path:
    1.42 +        pathname = join(dirname, filename)
    1.43 +        if isfile(pathname):
    1.44 +            module = parseFile(pathname)
    1.45 +            break
    1.46 +    else:
    1.47 +        return {}
    1.48 +
    1.49 +    return get_config_data(module, {})
    1.50 +
    1.51 +def get_config_data(module, d):
    1.52 +
    1.53 +    "Interpret the parsed 'module', storing mappings in 'd'."
    1.54 +
    1.55 +    name = None
    1.56 +
    1.57 +    for node in module.getChildNodes():
    1.58 +        if isinstance(node, (Module, Stmt)):
    1.59 +            get_config_data(node, d)
    1.60 +        elif isinstance(node, Discard):
    1.61 +            pass
    1.62 +        elif isinstance(node, Assign):
    1.63 +            if len(node.nodes) == 1 and isinstance(node.nodes[0], AssName):
    1.64 +                name = node.nodes[0].name
    1.65 +                if isinstance(node.expr, Const):
    1.66 +                    d[name] = node.expr.value
    1.67 +                elif isinstance(node.expr, Name):
    1.68 +                    d[name] = d.get(node.expr.name, builtins.get(node.expr.name))
    1.69 +
    1.70 +    return d
    1.71 +
    1.72 +# Expose settings via a module-level name.
    1.73 +
    1.74 +settings = get_config()
    1.75 +
    1.76 +# vim: tabstop=4 expandtab shiftwidth=4
     2.1 --- a/imiptools/config.txt	Mon Jan 30 23:23:30 2017 +0100
     2.2 +++ b/imiptools/config.txt	Mon Jan 30 23:28:11 2017 +0100
     2.3 @@ -1,7 +1,3 @@
     2.4 -#!/usr/bin/env python
     2.5 -
     2.6 -"Configuration settings for imiptools programs."
     2.7 -
     2.8  # The public identity of the agent.
     2.9  
    2.10  MESSAGE_SENDER = "calendar@example.com"
    2.11 @@ -138,5 +134,3 @@
    2.12  # length is used (which should be 76 characters).
    2.13  
    2.14  CALENDAR_LINE_LENGTH = None
    2.15 -
    2.16 -# vim: tabstop=4 expandtab shiftwidth=4
     3.1 --- a/imiptools/content.py	Mon Jan 30 23:23:30 2017 +0100
     3.2 +++ b/imiptools/content.py	Mon Jan 30 23:28:11 2017 +0100
     3.3 @@ -3,7 +3,7 @@
     3.4  """
     3.5  The handler invocation mechanism.
     3.6  
     3.7 -Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
     3.8 +Copyright (C) 2014, 2015, 2017 Paul Boddie <paul@boddie.org.uk>
     3.9  
    3.10  This program is free software; you can redistribute it and/or modify it under
    3.11  the terms of the GNU General Public License as published by the Free Software
    3.12 @@ -19,7 +19,7 @@
    3.13  this program.  If not, see <http://www.gnu.org/licenses/>.
    3.14  """
    3.15  
    3.16 -from imiptools.config import IMIP_COUNTER_AS_REQUEST
    3.17 +from imiptools.config import settings
    3.18  from imiptools.data import Object, parse_object, get_value
    3.19  
    3.20  try:
    3.21 @@ -27,6 +27,8 @@
    3.22  except ImportError:
    3.23      from StringIO import StringIO
    3.24  
    3.25 +IMIP_COUNTER_AS_REQUEST = settings["IMIP_COUNTER_AS_REQUEST"]
    3.26 +
    3.27  def handle_itip_part(part, handlers):
    3.28  
    3.29      """
     4.1 --- a/imiptools/filesys.py	Mon Jan 30 23:23:30 2017 +0100
     4.2 +++ b/imiptools/filesys.py	Mon Jan 30 23:28:11 2017 +0100
     4.3 @@ -3,7 +3,7 @@
     4.4  """
     4.5  Filesystem utilities.
     4.6  
     4.7 -Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
     4.8 +Copyright (C) 2014, 2015, 2017 Paul Boddie <paul@boddie.org.uk>
     4.9  
    4.10  This program is free software; you can redistribute it and/or modify it under
    4.11  the terms of the GNU General Public License as published by the Free Software
    4.12 @@ -20,11 +20,14 @@
    4.13  """
    4.14  
    4.15  import errno
    4.16 -from imiptools.config import DEFAULT_PERMISSIONS, DEFAULT_DIR_PERMISSIONS
    4.17 +from imiptools.config import settings
    4.18  from os.path import abspath, commonprefix, exists, join, split
    4.19  from os import chmod, getpid, makedirs, mkdir, rename, rmdir
    4.20  from time import sleep, time
    4.21  
    4.22 +DEFAULT_PERMISSIONS = settings["DEFAULT_PERMISSIONS"]
    4.23 +DEFAULT_DIR_PERMISSIONS = settings["DEFAULT_DIR_PERMISSIONS"]
    4.24 +
    4.25  def check_dir(base, filename):
    4.26  
    4.27      "Return whether 'base' contains 'filename'."
     5.1 --- a/imiptools/handlers/__init__.py	Mon Jan 30 23:23:30 2017 +0100
     5.2 +++ b/imiptools/handlers/__init__.py	Mon Jan 30 23:28:11 2017 +0100
     5.3 @@ -3,7 +3,7 @@
     5.4  """
     5.5  General handler support for incoming calendar objects.
     5.6  
     5.7 -Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
     5.8 +Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     5.9  
    5.10  This program is free software; you can redistribute it and/or modify it under
    5.11  the terms of the GNU General Public License as published by the Free Software
    5.12 @@ -21,11 +21,15 @@
    5.13  
    5.14  from email.mime.text import MIMEText
    5.15  from imiptools.client import ClientForObject
    5.16 -from imiptools.config import MANAGER_PATH, MANAGER_URL, MANAGER_URL_SCHEME
    5.17 +from imiptools.config import settings
    5.18  from imiptools.data import check_delegation, get_address, get_uri, \
    5.19                             get_sender_identities, uri_dict, uri_item
    5.20  from socket import gethostname
    5.21  
    5.22 +MANAGER_PATH = settings["MANAGER_PATH"]
    5.23 +MANAGER_URL = settings["MANAGER_URL"]
    5.24 +MANAGER_URL_SCHEME = settings["MANAGER_URL_SCHEME"]
    5.25 +
    5.26  # References to the Web interface.
    5.27  
    5.28  def get_manager_url():
     6.1 --- a/imiptools/i18n.py	Mon Jan 30 23:23:30 2017 +0100
     6.2 +++ b/imiptools/i18n.py	Mon Jan 30 23:28:11 2017 +0100
     6.3 @@ -3,7 +3,7 @@
     6.4  """
     6.5  Internationalisation support.
     6.6  
     6.7 -Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
     6.8 +Copyright (C) 2015, 2017 Paul Boddie <paul@boddie.org.uk>
     6.9  
    6.10  This program is free software; you can redistribute it and/or modify it under
    6.11  the terms of the GNU General Public License as published by the Free Software
    6.12 @@ -19,10 +19,13 @@
    6.13  this program.  If not, see <http://www.gnu.org/licenses/>.
    6.14  """
    6.15  
    6.16 -from imiptools.config import LOCALE_DIR, TRANS_DOMAIN
    6.17 +from imiptools.config import settings
    6.18  from os.path import abspath, exists, join, split
    6.19  import gettext
    6.20  
    6.21 +LOCALE_DIR = settings["LOCALE_DIR"]
    6.22 +TRANS_DOMAIN = settings["TRANS_DOMAIN"]
    6.23 +
    6.24  def get_locale_dir():
    6.25      locale_dir = abspath(join(split(__file__)[0], "..", "locale"))
    6.26      if exists(locale_dir):
     7.1 --- a/imiptools/mail.py	Mon Jan 30 23:23:30 2017 +0100
     7.2 +++ b/imiptools/mail.py	Mon Jan 30 23:28:11 2017 +0100
     7.3 @@ -3,7 +3,7 @@
     7.4  """
     7.5  Mail preparation support.
     7.6  
     7.7 -Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
     7.8 +Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     7.9  
    7.10  This program is free software; you can redistribute it and/or modify it under
    7.11  the terms of the GNU General Public License as published by the Free Software
    7.12 @@ -19,12 +19,16 @@
    7.13  this program.  If not, see <http://www.gnu.org/licenses/>.
    7.14  """
    7.15  
    7.16 -from imiptools.config import LOCAL_PREFIX, MESSAGE_SENDER, OUTGOING_PREFIX
    7.17 +from imiptools.config import settings
    7.18  from email.mime.message import MIMEMessage
    7.19  from email.mime.multipart import MIMEMultipart
    7.20  from email.mime.text import MIMEText
    7.21  from smtplib import LMTP, SMTP
    7.22  
    7.23 +LOCAL_PREFIX = settings["LOCAL_PREFIX"]
    7.24 +MESSAGE_SENDER = settings["MESSAGE_SENDER"]
    7.25 +OUTGOING_PREFIX = settings["OUTGOING_PREFIX"]
    7.26 +
    7.27  # Fake gettext function for strings to be translated later.
    7.28  
    7.29  _ = lambda s: s
     8.1 --- a/imiptools/profile.py	Mon Jan 30 23:23:30 2017 +0100
     8.2 +++ b/imiptools/profile.py	Mon Jan 30 23:28:11 2017 +0100
     8.3 @@ -3,7 +3,7 @@
     8.4  """
     8.5  User profile management.
     8.6  
     8.7 -Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
     8.8 +Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     8.9  
    8.10  This program is free software; you can redistribute it and/or modify it under
    8.11  the terms of the GNU General Public License as published by the Free Software
    8.12 @@ -19,7 +19,7 @@
    8.13  this program.  If not, see <http://www.gnu.org/licenses/>.
    8.14  """
    8.15  
    8.16 -from imiptools import config
    8.17 +from imiptools.config import settings
    8.18  from imiptools.dates import get_default_timezone
    8.19  from imiptools.filesys import fix_permissions, FileBase
    8.20  from os.path import exists, isdir
    8.21 @@ -42,18 +42,18 @@
    8.22  
    8.23      known_keys = {
    8.24          "CN"                    : "",
    8.25 -        "LANG"                  : config.LANG,
    8.26          "TZID"                  : get_default_timezone(),
    8.27 -        "add_method_response"   : config.ADD_RESPONSE_DEFAULT,
    8.28 -        "event_refreshing"      : config.REFRESHING_DEFAULT,
    8.29 -        "freebusy_bundling"     : config.BUNDLING_DEFAULT,
    8.30 -        "freebusy_messages"     : config.NOTIFYING_DEFAULT,
    8.31 -        "freebusy_offers"       : config.FREEBUSY_OFFER_DEFAULT,
    8.32 -        "freebusy_publishing"   : config.PUBLISHING_DEFAULT,
    8.33 -        "freebusy_sharing"      : config.SHARING_DEFAULT,
    8.34 -        "incoming"              : config.INCOMING_DEFAULT,
    8.35 -        "organiser_replacement" : config.ORGANISER_REPLACEMENT_DEFAULT,
    8.36 -        "participating"         : config.PARTICIPATING_DEFAULT,
    8.37 +        "LANG"                  : settings["LANG"],
    8.38 +        "add_method_response"   : settings["ADD_RESPONSE_DEFAULT"],
    8.39 +        "event_refreshing"      : settings["REFRESHING_DEFAULT"],
    8.40 +        "freebusy_bundling"     : settings["BUNDLING_DEFAULT"],
    8.41 +        "freebusy_messages"     : settings["NOTIFYING_DEFAULT"],
    8.42 +        "freebusy_offers"       : settings["FREEBUSY_OFFER_DEFAULT"],
    8.43 +        "freebusy_publishing"   : settings["PUBLISHING_DEFAULT"],
    8.44 +        "freebusy_sharing"      : settings["SHARING_DEFAULT"],
    8.45 +        "incoming"              : settings["INCOMING_DEFAULT"],
    8.46 +        "organiser_replacement" : settings["ORGANISER_REPLACEMENT_DEFAULT"],
    8.47 +        "participating"         : settings["PARTICIPATING_DEFAULT"],
    8.48          "permitted_times"       : None,
    8.49          }
    8.50  
    8.51 @@ -103,7 +103,7 @@
    8.52          }
    8.53  
    8.54      def __init__(self, user, store_dir=None):
    8.55 -        FileBase.__init__(self, store_dir or config.PREFERENCES_DIR)
    8.56 +        FileBase.__init__(self, store_dir or settings["PREFERENCES_DIR"])
    8.57          self.user = user
    8.58  
    8.59      def get(self, name, default=None, config_default=False):
     9.1 --- a/imiptools/stores/database/postgresql.py	Mon Jan 30 23:23:30 2017 +0100
     9.2 +++ b/imiptools/stores/database/postgresql.py	Mon Jan 30 23:28:11 2017 +0100
     9.3 @@ -3,7 +3,7 @@
     9.4  """
     9.5  A PostgreSQL database store of calendar data.
     9.6  
     9.7 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
     9.8 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     9.9  
    9.10  This program is free software; you can redistribute it and/or modify it under
    9.11  the terms of the GNU General Public License as published by the Free Software
    9.12 @@ -19,10 +19,13 @@
    9.13  this program.  If not, see <http://www.gnu.org/licenses/>.
    9.14  """
    9.15  
    9.16 -from imiptools.config import STORE_DIR, JOURNAL_DIR
    9.17 +from imiptools.config import settings
    9.18  from imiptools.stores.database.common import DatabaseStore, DatabaseJournal
    9.19  import psycopg2
    9.20  
    9.21 +STORE_DIR = settings["STORE_DIR"]
    9.22 +JOURNAL_DIR = settings["JOURNAL_DIR"]
    9.23 +
    9.24  class Store(DatabaseStore):
    9.25  
    9.26      "A PostgreSQL database store of calendar objects and free/busy data."
    10.1 --- a/imiptools/stores/file.py	Mon Jan 30 23:23:30 2017 +0100
    10.2 +++ b/imiptools/stores/file.py	Mon Jan 30 23:28:11 2017 +0100
    10.3 @@ -3,7 +3,7 @@
    10.4  """
    10.5  A simple filesystem-based store of calendar data.
    10.6  
    10.7 -Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
    10.8 +Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
    10.9  
   10.10  This program is free software; you can redistribute it and/or modify it under
   10.11  the terms of the GNU General Public License as published by the Free Software
   10.12 @@ -22,7 +22,7 @@
   10.13  from imiptools.stores.common import StoreBase, PublisherBase, JournalBase
   10.14  
   10.15  from datetime import datetime
   10.16 -from imiptools.config import STORE_DIR, PUBLISH_DIR, JOURNAL_DIR
   10.17 +from imiptools.config import settings
   10.18  from imiptools.data import make_calendar, parse_object, to_stream
   10.19  from imiptools.dates import format_datetime, get_datetime, to_timezone
   10.20  from imiptools.filesys import fix_permissions, FileBase
   10.21 @@ -34,6 +34,10 @@
   10.22  from os import listdir, remove, rmdir
   10.23  import codecs
   10.24  
   10.25 +STORE_DIR = settings["STORE_DIR"]
   10.26 +PUBLISH_DIR = settings["PUBLISH_DIR"]
   10.27 +JOURNAL_DIR = settings["JOURNAL_DIR"]
   10.28 +
   10.29  class FileStoreBase(FileBase):
   10.30  
   10.31      "A file store supporting user-specific locking and tabular data."
    11.1 --- a/tools/install.sh	Mon Jan 30 23:23:30 2017 +0100
    11.2 +++ b/tools/install.sh	Mon Jan 30 23:28:11 2017 +0100
    11.3 @@ -78,21 +78,41 @@
    11.4      rm "$INSTALL_DIR/imip_store.py"*
    11.5  fi
    11.6  
    11.7 -# Install the config module in a more appropriate location.
    11.8 +# Install the configuration in a more appropriate location.
    11.9  # Create new versions of configuration files instead of overwriting.
   11.10  
   11.11  if [ ! -e "$CONFIG_DIR" ]; then
   11.12      mkdir -p "$CONFIG_DIR"
   11.13  fi
   11.14  
   11.15 +# Handle any old config module in the configuration location.
   11.16 +
   11.17  if [ -e "$CONFIG_DIR/config.py" ]; then
   11.18 -    if ! cmp "$INSTALL_DIR/imiptools/config.py" "$CONFIG_DIR/config.py" > /dev/null 2>&1 ; then
   11.19 -        mv "$INSTALL_DIR/imiptools/config.py" "$CONFIG_DIR/config.py.new"
   11.20 +
   11.21 +    # Rename the old config module.
   11.22 +
   11.23 +    mv "$CONFIG_DIR/config.py" "$CONFIG_DIR/config.txt"
   11.24 +fi
   11.25 +
   11.26 +# Handle any existing configuration file in the configuration location.
   11.27 +
   11.28 +if [ -e "$CONFIG_DIR/config.txt" ]; then
   11.29 +
   11.30 +    # Install the new configuration file alongside the existing file if
   11.31 +    # different.
   11.32 +
   11.33 +    if ! cmp "$INSTALL_DIR/imiptools/config.txt" "$CONFIG_DIR/config.txt" > /dev/null 2>&1 ; then
   11.34 +        cp "$INSTALL_DIR/imiptools/config.txt" "$CONFIG_DIR/config.txt.new"
   11.35      fi
   11.36 +
   11.37 +# Otherwise, just copy the configuration file.
   11.38 +
   11.39  else
   11.40 -    mv "$INSTALL_DIR/imiptools/config.py" "$CONFIG_DIR/config.py"
   11.41 +    cp "$INSTALL_DIR/imiptools/config.txt" "$CONFIG_DIR/config.txt"
   11.42  fi
   11.43  
   11.44 +# Update the tools configuration file.
   11.45 +
   11.46  if [ -e "$CONFIG_DIR/config.sh" ]; then
   11.47      if ! cmp "tools/config.sh" "$CONFIG_DIR/config.sh" > /dev/null 2>&1 ; then
   11.48          cp "tools/config.sh" "$CONFIG_DIR/config.sh.new"
   11.49 @@ -101,10 +121,6 @@
   11.50      cp "tools/config.sh" "$CONFIG_DIR/config.sh"
   11.51  fi
   11.52  
   11.53 -# Replace the config module with a symbolic link.
   11.54 -
   11.55 -ln -s "$CONFIG_DIR/config.py" "$INSTALL_DIR/imiptools/config.py"
   11.56 -
   11.57  # Copy related configuration files.
   11.58  
   11.59  if [ ! -e "$CONFIG_DIR/postgresql" ]; then