comparison roundup/configuration.py @ 2654:eccb8e15a83f

implemented section comments; fix Config.load_ini(): HOME was not passed in defaults; CoreConfig: don't require MAIL_PASSWORD if MAIL_USERNAME is not set
author Alexander Smishlajev <a1s@users.sourceforge.net>
date Wed, 28 Jul 2004 09:46:58 +0000
parents 1df7d4a41da4
children cdf6787ffeda
comparison
equal deleted inserted replaced
2653:09e0d37abada 2654:eccb8e15a83f
1 # Roundup Issue Tracker configuration support 1 # Roundup Issue Tracker configuration support
2 # 2 #
3 # $Id: configuration.py,v 1.15 2004-07-28 02:29:45 richard Exp $ 3 # $Id: configuration.py,v 1.16 2004-07-28 09:46:58 a1s Exp $
4 # 4 #
5 __docformat__ = "restructuredtext" 5 __docformat__ = "restructuredtext"
6 6
7 import imp 7 import imp
8 import os 8 import os
453 (MailAddressOption, "email", "issue_tracker", 453 (MailAddressOption, "email", "issue_tracker",
454 "Email address that mail to roundup should go to."), 454 "Email address that mail to roundup should go to."),
455 )), 455 )),
456 ("rdbms", ( 456 ("rdbms", (
457 (Option, 'name', 'roundup', 457 (Option, 'name', 'roundup',
458 "Name of the Postgresql or MySQL database to use.", 458 "Name of the database to use.",
459 ['MYSQL_DBNAME']), 459 ['MYSQL_DBNAME']),
460 (NullableOption, 'host', 'localhost', 460 (NullableOption, 'host', 'localhost',
461 "Hostname that the Postgresql or MySQL database resides on.", 461 "Database server host.",
462 ['MYSQL_DBHOST']), 462 ['MYSQL_DBHOST']),
463 (NullableOption, 'port', '', 463 (NullableOption, 'port', '',
464 "Port number that the Postgresql or MySQL database resides on."), 464 "TCP port number of the database server.\n"
465 "Postgresql usually resides on port 5432 (if any),\n"
466 "for MySQL default port number is 3306.\n"
467 "Leave this option empty to use backend default"),
465 (NullableOption, 'user', 'roundup', 468 (NullableOption, 'user', 'roundup',
466 "Postgresql or MySQL database user that Roundup should use.", 469 "Database user name that Roundup should use.",
467 ['MYSQL_DBUSER']), 470 ['MYSQL_DBUSER']),
468 (NullableOption, 'password', 'roundup', 471 (NullableOption, 'password', 'roundup',
469 "Password for the Postgresql or MySQL database user.", 472 "Database user password.",
470 ['MYSQL_DBPASSWORD']), 473 ['MYSQL_DBPASSWORD']),
471 )), 474 ), "Settings in this section are used"
475 " by Postgresql and MySQL backends only"
476 ),
472 ("logging", ( 477 ("logging", (
473 (FilePathOption, "config", "", 478 (FilePathOption, "config", "",
474 "Path to configuration file for standard Python logging module.\n" 479 "Path to configuration file for standard Python logging module.\n"
475 "If this option is set, logging configuration is loaded\n" 480 "If this option is set, logging configuration is loaded\n"
476 "from specified file; options 'filename' and 'level'\n" 481 "from specified file; options 'filename' and 'level'\n"
512 (FilePathOption, "debug", "", 517 (FilePathOption, "debug", "",
513 "Setting this option makes Roundup to write all outgoing email\n" 518 "Setting this option makes Roundup to write all outgoing email\n"
514 "messages to this file *instead* of sending them.\n" 519 "messages to this file *instead* of sending them.\n"
515 "This option has the same effect as environment variable" 520 "This option has the same effect as environment variable"
516 " SENDMAILDEBUG.\nEnvironment variable takes precedence."), 521 " SENDMAILDEBUG.\nEnvironment variable takes precedence."),
517 )), 522 ), "Outgoing email options.\nUsed for nozy messages and approval requests"),
518 ("mailgw", ( 523 ("mailgw", (
519 (BooleanOption, "keep_quoted_text", "yes", 524 (BooleanOption, "keep_quoted_text", "yes",
520 "Keep email citations when accepting messages.\n" 525 "Keep email citations when accepting messages.\n"
521 "Setting this to \"no\" strips out \"quoted\" text" 526 "Setting this to \"no\" strips out \"quoted\" text"
522 " from the message.\n" 527 " from the message.\n"
529 (Option, "default_class", "issue", 534 (Option, "default_class", "issue",
530 "Default class to use in the mailgw\n" 535 "Default class to use in the mailgw\n"
531 "if one isn't supplied in email subjects.\n" 536 "if one isn't supplied in email subjects.\n"
532 "To disable, leave the value blank.", 537 "To disable, leave the value blank.",
533 ["MAIL_DEFAULT_CLASS"]), 538 ["MAIL_DEFAULT_CLASS"]),
534 )), 539 ), "Roundup Mail Gateway options"),
535 ("nosy", ( 540 ("nosy", (
536 (RunDetectorOption, "messages_to_author", "no", 541 (RunDetectorOption, "messages_to_author", "no",
537 "Send nosy messages to the author of the message.", 542 "Send nosy messages to the author of the message.",
538 ["MESSAGES_TO_AUTHOR"]), 543 ["MESSAGES_TO_AUTHOR"]),
539 (Option, "signature_position", "bottom", 544 (Option, "signature_position", "bottom",
552 "nosy list? If 'new' is used, then the recipients will\n" 557 "nosy list? If 'new' is used, then the recipients will\n"
553 "only be added when a message creates a new issue.\n" 558 "only be added when a message creates a new issue.\n"
554 "If 'yes', then the recipients will be added on followups too.\n" 559 "If 'yes', then the recipients will be added on followups too.\n"
555 "If 'no', they're never added to the nosy.\n", 560 "If 'no', they're never added to the nosy.\n",
556 ["ADD_RECIPIENTS_TO_NOSY"]), 561 ["ADD_RECIPIENTS_TO_NOSY"]),
557 )), 562 ), "Nosy messages sending"),
558 ) 563 )
559 564
560 ### Configuration classes 565 ### Configuration classes
561 566
562 class Config: 567 class Config:
758 """ 763 """
759 # parse the file 764 # parse the file
760 config_defaults = {"HOME": home_dir} 765 config_defaults = {"HOME": home_dir}
761 if defaults: 766 if defaults:
762 config_defaults.update(defaults) 767 config_defaults.update(defaults)
763 _config = ConfigParser.ConfigParser(defaults) 768 config = ConfigParser.ConfigParser(config_defaults)
764 _config.read([os.path.join(home_dir, self.INI_FILE)]) 769 config.read([os.path.join(home_dir, self.INI_FILE)])
765 # .ini file loaded ok. set the options, starting from HOME 770 # .ini file loaded ok. set the options, starting from HOME
766 self.reset() 771 self.reset()
767 self.HOME = home_dir 772 self.HOME = home_dir
768 for _option in self.items(): 773 for option in self.items():
769 _option.load_ini(_config) 774 option.load_ini(config)
770 775
771 def load(self, home_dir): 776 def load(self, home_dir):
772 """Load configuration settings from home_dir""" 777 """Load configuration settings from home_dir"""
773 self.load_ini(home_dir) 778 self.load_ini(home_dir)
774 779
794 need_set = self._get_unset_options() 799 need_set = self._get_unset_options()
795 if need_set: 800 if need_set:
796 _fp.write("\n# WARNING! Following options need adjustments:\n") 801 _fp.write("\n# WARNING! Following options need adjustments:\n")
797 for section, options in need_set.items(): 802 for section, options in need_set.items():
798 _fp.write("# [%s]: %s\n" % (section, ", ".join(options))) 803 _fp.write("# [%s]: %s\n" % (section, ", ".join(options)))
799 for _section in self.sections: 804 for section in self.sections:
800 _fp.write("\n[%s]\n" % _section) 805 comment = self.section_descriptions.get(section, None)
801 for _option in self._get_section_options(_section): 806 if comment:
802 _fp.write("\n" + self.options[(_section, _option)].format()) 807 _fp.write("\n# ".join([""] + comment.split("\n")) +"\n")
808 else:
809 # no section comment - just leave a blank line between sections
810 _fp.write("\n")
811 _fp.write("[%s]\n" % section)
812 for option in self._get_section_options(section):
813 _fp.write("\n" + self.options[(section, option)].format())
803 _fp.close() 814 _fp.close()
804 if os.access(ini_file, os.F_OK): 815 if os.access(ini_file, os.F_OK):
805 if os.access(_bak_file, os.F_OK): 816 if os.access(_bak_file, os.F_OK):
806 os.remove(_bak_file) 817 os.remove(_bak_file)
807 os.rename(ini_file, _bak_file) 818 os.rename(ini_file, _bak_file)
918 class CoreConfig(Config): 929 class CoreConfig(Config):
919 930
920 """Roundup instance configuration. 931 """Roundup instance configuration.
921 932
922 Core config has a predefined layout (see the SETTINGS structure), 933 Core config has a predefined layout (see the SETTINGS structure),
923 support loading of old-style pythonic configurations and hold 934 supports loading of old-style pythonic configurations and holds
924 three additional attributes: 935 three additional attributes:
925 logging: 936 logging:
926 instance logging engine, from standard python logging module 937 instance logging engine, from standard python logging module
927 or minimalistic logger implemented in Roundup 938 or minimalistic logger implemented in Roundup
928 detectors: 939 detectors:
944 Config.__init__(self, home_dir, SETTINGS) 955 Config.__init__(self, home_dir, SETTINGS)
945 # load the config if home_dir given 956 # load the config if home_dir given
946 if home_dir is None: 957 if home_dir is None:
947 self.init_logging() 958 self.init_logging()
948 959
949 # TODO: remove MAIL_PASSWORD if MAIL_USER is empty 960 def _get_unset_options(self):
950 #def _get_unset_options(self): 961 need_set = Config._get_unset_options(self)
962 # remove MAIL_PASSWORD if MAIL_USER is empty
963 if "password" in need_set.get("mail", []):
964 if not self["MAIL_USERNAME"]:
965 settings = need_set["mail"]
966 settings.remove("password")
967 if not settings:
968 del need_set["mail"]
969 return need_set
951 970
952 def reset(self): 971 def reset(self):
953 Config.reset(self) 972 Config.reset(self)
954 if self.ext: 973 if self.ext:
955 self.ext.reset() 974 self.ext.reset()

Roundup Issue Tracker: http://roundup-tracker.org/