Ejemplo n.º 1
0
    def load_ini(self, ini_config):
        """
        Read the provided ini contents arguments and merge
        the data in the ini config into the config object.

        ini_config is assumed to be a string of the ini file contents.
        """
        parser = ConfigParser()
        parser.readfp(StringIO(ini_config))
        data = {
            'linters': {},
            'files': {},
            'branches': {},
        }
        if parser.has_section('files'):
            ignore = parser.get('files', 'ignore')
            data['files']['ignore'] = newline_value(ignore)
        if parser.has_section('branches'):
            ignore = parser.get('branches', 'ignore')
            data['branches']['ignore'] = comma_value(ignore)

        linters = []
        if parser.has_section('tools'):
            linters = comma_value(parser.get('tools', 'linters'))
        # Setup empty config sections
        for linter in linters:
            data['linters'][linter] = {}
        for section in parser.sections():
            if not section.startswith('tool_'):
                continue
            # Strip off tool_
            linter = section[5:]
            data['linters'][linter] = dict(parser.items(section))
        self.update(data)
Ejemplo n.º 2
0
    def autologin(self, section=None):
        """Login to Open Library with credentials taken from ~/.olrc file.

        The ~/.olrc file must be in ini format (format readable by
        configparser module) and there should be a section with the
        server name. A sample configuration file may look like this::

            [openlibrary.org]
            username = joe
            password = secret

            [0.0.0.0:8080]
            username = joe
            password = joe123

        Optionally section name can be passed as argument to force using a different section name.

        If environment variable OPENLIBRARY_RCFILE is specified, it'll read that file instead of ~/.olrc.
        """
        config = ConfigParser()

        configfile = os.getenv('OPENLIBRARY_RCFILE',
                               os.path.expanduser('~/.olrc'))
        logger.info("reading %s", configfile)
        config.read(configfile)

        section = section or self.base_url.split('://')[-1]

        if not config.has_section(section):
            raise Exception("No section found with name %s in ~/.olrc" %
                            repr(section))

        username = config.get(section, 'username')
        password = config.get(section, 'password')
        return self.login(username, password)
Ejemplo n.º 3
0
def partition_defaultboot(partition):
    try:
        settings_path = partition_mount(
            config.DATA['system']['settings_partition'], 'rw')
        conf_path = os.path.join(settings_path, 'noobs.conf')

        noobs_conf = ConfigParser()
        noobs_conf.read(conf_path)

        section = 'General'

        if not noobs_conf.has_section(section):
            noobs_conf.add_section(section)

        if partition == config.DATA['system']['recovery_partition']:
            noobs_conf.remove_option(section, 'default_partition_to_boot')
            noobs_conf.remove_option(section, 'sticky_boot')
        else:
            noobs_conf.set(section, 'default_partition_to_boot',
                           str(partition_number(partition)))
            noobs_conf.set(section, 'sticky_boot',
                           str(partition_number(partition)))

        output = StringIO()
        noobs_conf.write(output)
        write_file(conf_path, output.getvalue())
    except:
        raise
    finally:
        partition_umount(config.DATA['system']['settings_partition'])
Ejemplo n.º 4
0
 def _get_names_from_config(self, cp, section):
     config = ConfigParser()
     config.read(cp)
     if config.has_section(section):
         return [
             config.get(section, option)
             for option in config.options(section)
         ]
Ejemplo n.º 5
0
def get_options_from_config(config_file):
    """Get configuration information from config like setup.cfg or tox.ini"""
    from six.moves.configparser import ConfigParser
    conf = ConfigParser()

    conf.read([config_file])
    if conf.has_section('changelog'):
        return dict(conf.items('changelog'))
    return {}
Ejemplo n.º 6
0
class INIReader(object):
    """ConfigParser wrapper able to cast value when reading INI options."""

    # Helper casters
    cast_boolean = casts.Boolean()
    cast_dict = casts.Dict()
    cast_list = casts.List()
    cast_logging_level = casts.LoggingLevel()
    cast_tuple = casts.Tuple()
    cast_webdriver_desired_capabilities = casts.WebdriverDesiredCapabilities()

    def __init__(self, path):
        self.config_parser = ConfigParser()
        with open(path) as handler:
            self.config_parser.readfp(handler)
            if sys.version_info[0] < 3:
                # ConfigParser.readfp is deprecated on Python3, read_file
                # replaces it
                self.config_parser.readfp(handler)
            else:
                self.config_parser.read_file(handler)

    def get(self, section, option, default=None, cast=None):
        """Read an option from a section of a INI file.

        The default value will return if the look up option is not available.
        The value will be cast using a callable if specified otherwise a string
        will be returned.

        :param section: Section to look for.
        :param option: Option to look for.
        :param default: The value that should be used if the option is not
            defined.
        :param cast: If provided the value will be cast using the cast
            provided.

        """
        try:
            value = self.config_parser.get(section, option)
            if cast is not None:
                if cast is bool:
                    value = self.cast_boolean(value)
                elif cast is dict:
                    value = self.cast_dict(value)
                elif cast is list:
                    value = self.cast_list(value)
                elif cast is tuple:
                    value = self.cast_tuple(value)
                else:
                    value = cast(value)
        except (NoSectionError, NoOptionError):
            value = default
        return value

    def has_section(self, section):
        """Check if section is available."""
        return self.config_parser.has_section(section)
Ejemplo n.º 7
0
class INIReader(object):
    """ConfigParser wrapper able to cast value when reading INI options."""
    # Helper casters
    cast_boolean = casts.Boolean()
    cast_dict = casts.Dict()
    cast_list = casts.List()
    cast_logging_level = casts.LoggingLevel()
    cast_tuple = casts.Tuple()
    cast_webdriver_desired_capabilities = casts.WebdriverDesiredCapabilities()

    def __init__(self, path):
        self.config_parser = ConfigParser()
        with open(path) as handler:
            self.config_parser.readfp(handler)
            if sys.version_info[0] < 3:
                # ConfigParser.readfp is deprecated on Python3, read_file
                # replaces it
                self.config_parser.readfp(handler)
            else:
                self.config_parser.read_file(handler)

    def get(self, section, option, default=None, cast=None):
        """Read an option from a section of a INI file.

        The default value will return if the look up option is not available.
        The value will be cast using a callable if specified otherwise a string
        will be returned.

        :param section: Section to look for.
        :param option: Option to look for.
        :param default: The value that should be used if the option is not
            defined.
        :param cast: If provided the value will be cast using the cast
            provided.

        """
        try:
            value = self.config_parser.get(section, option)
            if cast is not None:
                if cast is bool:
                    value = self.cast_boolean(value)
                elif cast is dict:
                    value = self.cast_dict(value)
                elif cast is list:
                    value = self.cast_list(value)
                elif cast is tuple:
                    value = self.cast_tuple(value)
                else:
                    value = cast(value)
        except (NoSectionError, NoOptionError):
            value = default
        return value

    def has_section(self, section):
        """Check if section is available."""
        return self.config_parser.has_section(section)
Ejemplo n.º 8
0
    def test_empty_dict(self):
        name = self.make_empty_temp_file()
        to_config_file(name, "section.name", {})

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
    def test_empty_dict(self):
        name = self.make_empty_temp_file()
        to_config_file(name, "section.name", {})

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
Ejemplo n.º 10
0
    def test_partial_dict(self):
        name = self.make_empty_temp_file()
        to_config_file(name, "section.name", {"port_queue_dt": 1.})

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
        self.assertEqual(1., config.getfloat("section.name", "port_queue_dt"))
    def test_partial_dict(self):
        name = self.make_empty_temp_file()
        to_config_file(name, "section.name", {"port_queue_dt": 1.})

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
        self.assertEqual(1., config.getfloat("section.name", "port_queue_dt"))
Ejemplo n.º 12
0
    def load_ini(self, ini_config):
        """
        Read the provided ini contents arguments and merge
        the data in the ini config into the config object.

        ini_config is assumed to be a string of the ini file contents.
        """
        parser = ConfigParser()
        parser.readfp(StringIO(ini_config))
        data = {
            'linters': {},
            'files': {},
            'branches': {},
            'fixers': {},
            'review': {}
        }
        if parser.has_section('files'):
            ignore = parser.get('files', 'ignore')
            data['files']['ignore'] = newline_value(ignore)
        if parser.has_section('branches'):
            ignore = parser.get('branches', 'ignore')
            data['branches']['ignore'] = comma_value(ignore)

        linters = []
        if parser.has_section('tools'):
            linters = comma_value(parser.get('tools', 'linters'))

        if parser.has_section('fixers'):
            data['fixers'] = dict(parser.items('fixers'))
        if parser.has_section('review'):
            data['review'] = dict(parser.items('review'))
        # Setup empty config sections
        for linter in linters:
            data['linters'][linter] = {}
        for section in parser.sections():
            if not section.startswith('tool_'):
                continue
            # Strip off tool_
            linter = section[5:]
            data['linters'][linter] = dict(parser.items(section))
        self.update(data)
Ejemplo n.º 13
0
class OSCAPConfig(object):
    _config_file = SCAP_BASEDIR + "/config"
    _section = "openscap"
    _profile = "profile"
    _datastream = "datastream"
    _configured = "configured"

    def __init__(self):
        self._cp = ConfigParser()
        self._cp.read(self._config_file)
        if not self._cp.has_section(self._section):
            self._cp.add_section(self._section)

    def _set_value(self, key, val):
        self._cp.set(self._section, key, val)
        self._save()

    def _get_value(self, key, default=None):
        if not self._cp.has_option(self._section, key):
            return default
        return self._cp.get(self._section, key)

    def _save(self):
        with open(self._config_file, "w") as f:
            self._cp.write(f)

    @property
    def profile(self):
        return self._get_value(self._profile)

    @profile.setter
    def profile(self, value):
        return self._set_value(self._profile, value)

    @property
    def datastream(self):
        return self._get_value(self._datastream)

    @datastream.setter
    def datastream(self, value):
        return self._set_value(self._datastream, value)

    @property
    def registered(self):
        return bool(self.profile and self.datastream)

    @property
    def configured(self):
        return self._get_value(self._configured)

    @configured.setter
    def configured(self, value):
        return self._set_value(self._configured, value)
Ejemplo n.º 14
0
    def __init__(self, config_file):
        config = ConfigParser(allow_no_value=True)
        config.read(config_file)

        self.serial = {
            "port": config.get('device', 'port'),
            "baudrate": config.getint('device', 'baudrate'),
            "parity": config.get('device', 'parity'),
            "bytesize": config.getint('device', 'bytesize'),
            "stopbits": config.getint('device', 'stopbits'),
            "timeout": config.getfloat('device', 'timeout'),
            "interCharTimeout": config.getfloat('device', 'char_delay'),
        }

        self.serial_char_delay = self.serial["interCharTimeout"]

        self.storage_dir = config.get("storage", "dir")

        self.sdb_enabled = config.has_section("simpledb")

        if self.sdb_enabled:
            self.sdb_domain = config.get("simpledb", "domain")

        if config.has_section("aws"):
            self.aws_access_key_id = config.get("aws", "access_key_id")
            self.aws_secret_access_key = config.get("aws", "secret_access_key")
            self.aws_region = config.get("aws", "region")

        self.station_id = config.get("site", "station_id")

        self.mail_enabled = config.has_section("mail")
        if self.mail_enabled:
            self.mail_host = config.get("mail", "host") or "localhost"
            self.mail_port = config.getint(
                "mail", "port") if config.has_option("mail", "port") else 587
            self.mail_username = config.get("mail", "username")
            self.mail_password = config.get("mail", "password")
            self.mail_to = config.get("mail", "to")
Ejemplo n.º 15
0
    def test_ignore_extra_params(self):
        name = self.make_empty_temp_file()
        to_config_file(
            name, "section.name", {"invalid_parameter": "empty", "port_queue_dt": 1.2}
        )

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
        self.assertEqual(1.2, config.getfloat("section.name", "port_queue_dt"))
        self.assertFalse(config.has_option("section.name", "invalid_parameter"))
Ejemplo n.º 16
0
def config(filename='database.ini', section='postgresql'):
    parser = ConfigParser()
    parser.read(filename)

    db = {}
    if parser.has_section(section):
        params = parser.items(section)
        for param in params:
            db[param[0]] = param[1]
    else:
        raise Exception('Section {0} not found in the {1} file'.format(
            section, filename))

    return db
Ejemplo n.º 17
0
  def load(self):
    schemes = [defaultScheme]
    parser = ConfigParser()
    parser.read(settings.DASHBOARD_CONF)

    for option, default_value in defaultUIConfig.items():
      if parser.has_option('ui', option):
        try:
          self.ui_config[option] = parser.getint('ui', option)
        except ValueError:
          self.ui_config[option] = parser.get('ui', option)
      else:
        self.ui_config[option] = default_value

    if parser.has_option('ui', 'automatic_variants'):
      self.ui_config['automatic_variants']   = parser.getboolean('ui', 'automatic_variants')
    else:
      self.ui_config['automatic_variants'] = True

    self.ui_config['keyboard_shortcuts'] = defaultKeyboardShortcuts.copy()
    if parser.has_section('keyboard-shortcuts'):
      self.ui_config['keyboard_shortcuts'].update( parser.items('keyboard-shortcuts') )

    for section in parser.sections():
      if section in ('ui', 'keyboard-shortcuts'):
        continue

      scheme = parser.get(section, 'scheme')
      fields = []

      for match in fieldRegex.finditer(scheme):
        field = match.group(1)
        if parser.has_option(section, '%s.label' % field):
          label = parser.get(section, '%s.label' % field)
        else:
          label = field

        fields.append({
          'name' : field,
          'label' : label
        })

      schemes.append({
        'name' : section,
        'pattern' : scheme,
        'fields' : fields,
      })

    self.schemes = schemes
Ejemplo n.º 18
0
  def load(self):
    schemes = [defaultScheme]
    parser = ConfigParser()
    parser.read(settings.DASHBOARD_CONF)

    for option, default_value in defaultUIConfig.items():
      if parser.has_option('ui', option):
        try:
          self.ui_config[option] = parser.getint('ui', option)
        except ValueError:
          self.ui_config[option] = parser.get('ui', option)
      else:
        self.ui_config[option] = default_value

    if parser.has_option('ui', 'automatic_variants'):
      self.ui_config['automatic_variants']   = parser.getboolean('ui', 'automatic_variants')
    else:
      self.ui_config['automatic_variants'] = True

    self.ui_config['keyboard_shortcuts'] = defaultKeyboardShortcuts.copy()
    if parser.has_section('keyboard-shortcuts'):
      self.ui_config['keyboard_shortcuts'].update( parser.items('keyboard-shortcuts') )

    for section in parser.sections():
      if section in ('ui', 'keyboard-shortcuts'):
        continue

      scheme = parser.get(section, 'scheme')
      fields = []

      for match in fieldRegex.finditer(scheme):
        field = match.group(1)
        if parser.has_option(section, '%s.label' % field):
          label = parser.get(section, '%s.label' % field)
        else:
          label = field

        fields.append({
          'name' : field,
          'label' : label
        })

      schemes.append({
        'name' : section,
        'pattern' : scheme,
        'fields' : fields,
      })

    self.schemes = schemes
    def test_ignore_extra_params(self):
        name = self.make_empty_temp_file()
        to_config_file(name, "section.name", {
            "invalid_parameter": "empty",
            "port_queue_dt": 1.2
        })

        self.assertTrue(os.path.isfile(name))

        config = ConfigParser()
        config.read(name)
        self.assertTrue(config.has_section("section.name"))
        self.assertSetEqual(_VALID_KEYS, set(config.options("section.name")))
        self.assertEqual(1.2, config.getfloat("section.name", "port_queue_dt"))
        self.assertFalse(config.has_option("section.name",
                                           "invalid_parameter"))
Ejemplo n.º 20
0
def login(conf):
    if conf.cli_args.token:
        token = conf.cli_args.token
    else:
        token = getpass.getpass('Token: ')
    flagrc_path = os.path.join(os.path.expanduser(conf.cli_args.config))

    print("Writing token to {}".format(flagrc_path))
    flagrc = ConfigParser()
    flagrc.read(flagrc_path)

    if not flagrc.has_section('iscore'):
        flagrc.add_section('iscore')

    flagrc.set('iscore', 'api_token', token)
    with open(flagrc_path, 'w') as fp:
        flagrc.write(fp)
Ejemplo n.º 21
0
Archivo: auth.py Proyecto: zwunix/st2
    def run(self, args, **kwargs):

        if not args.password:
            args.password = getpass.getpass()
        instance = self.resource(ttl=args.ttl) if args.ttl else self.resource()

        cli = BaseCLIApp()

        # Determine path to config file
        try:
            config_file = cli._get_config_file_path(args)
        except ValueError:
            # config file not found in args or in env, defaulting
            config_file = config_parser.ST2_CONFIG_PATH

        # Retrieve token
        manager = self.manager.create(instance,
                                      auth=(args.username, args.password),
                                      **kwargs)
        cli._cache_auth_token(token_obj=manager)

        # Update existing configuration with new credentials
        config = ConfigParser()
        config.read(config_file)

        # Modify config (and optionally populate with password)
        if not config.has_section('credentials'):
            config.add_section('credentials')

        config.set('credentials', 'username', args.username)
        if args.write_password:
            config.set('credentials', 'password', args.password)
        else:
            # Remove any existing password from config
            config.remove_option('credentials', 'password')

        config_existed = os.path.exists(config_file)
        with open(config_file, 'w') as cfg_file_out:
            config.write(cfg_file_out)
        # If we created the config file, correct the permissions
        if not config_existed:
            os.chmod(config_file, 0o660)

        return manager
def read_db_config(filename='/path/to/your/directory/rpi_control/config.ini', section='mysql'):
    """ Read database configuration file and return a dictionary object
    :param filename: name of the configuration file
    :param section: section of database configuration
    :return: a dictionary of database parameters
    """
    # create parser and read ini configuration file
    parser = ConfigParser()
    parser.read(filename)
 
    # get section, default to mysql
    db = {}
    if parser.has_section(section):
        items = parser.items(section)
        for item in items:
            db[item[0]] = item[1]
    else:
        raise Exception('{0} not found in the {1} file'.format(section, filename))
 
    return db
    print db
Ejemplo n.º 23
0
Archivo: auth.py Proyecto: lyandut/st2
    def run(self, args, **kwargs):

        if not args.password:
            args.password = getpass.getpass()
        instance = self.resource(ttl=args.ttl) if args.ttl else self.resource()

        cli = BaseCLIApp()

        # Determine path to config file
        try:
            config_file = cli._get_config_file_path(args)
        except ValueError:
            # config file not found in args or in env, defaulting
            config_file = config_parser.ST2_CONFIG_PATH

        # Retrieve token
        manager = self.manager.create(instance, auth=(args.username, args.password), **kwargs)
        cli._cache_auth_token(token_obj=manager)

        # Update existing configuration with new credentials
        config = ConfigParser()
        config.read(config_file)

        # Modify config (and optionally populate with password)
        if not config.has_section('credentials'):
            config.add_section('credentials')

        config.set('credentials', 'username', args.username)
        if args.write_password:
            config.set('credentials', 'password', args.password)
        else:
            # Remove any existing password from config
            config.remove_option('credentials', 'password')

        with open(config_file, 'w') as cfg_file_out:
            config.write(cfg_file_out)

        return manager
Ejemplo n.º 24
0
class StageConfig(object):
    def __init__(self, filename=None, text=None):
        self.config = {}
        self.cp = ConfigParser()
        self.nstages = 0
        fname = None
        if filename is not None and os.path.exists(filename):
            fname = filename
        if fname is None:
            for filename in conf_files:
                if os.path.exists(filename) and os.path.isfile(filename):
                    fname = filename
                    break

        if fname is not None:
            self.Read(fname=fname)
        else:
            self.cp.readfp(StringIO(DEFAULT_CONF))
            self._process_data()

    def Read(self, fname=None):
        if fname is not None:
            ret = self.cp.read(fname)
            if len(ret) == 0:
                time.sleep(0.5)
                ret = self.cp.read(fname)
            self.filename = fname
            self._process_data()

            stage_names = self.config['stages']
            image_folder = self.config['camera']['image_folder']
            pos = OrderedDict()
            if 'positions' not in self.config:
                self.config['positions'] = {}
            for key, dat in self.config['positions'].items():
                img_fname = dat['image']
                image = {
                    'type': 'filename',
                    'data': os.path.join(image_folder, img_fname)
                }

                poslist = dat['position']
                posdict = {}
                for name, val in zip(stage_names, poslist):
                    posdict[name] = val
                pos[key] = dict(image=image, position=posdict)
            self.config['positions'] = pos

    def _process_data(self):
        for sect, opts in conf_sects.items():
            if not self.cp.has_section(sect):
                # print 'skipping section ' ,sect
                continue
            bools = opts.get('bools', [])
            floats = opts.get('floats', [])
            ints = opts.get('ints', [])
            thissect = {}
            is_ordered = False
            if 'ordered' in opts:
                is_ordered = True

            for opt in self.cp.options(sect):
                get = self.cp.get
                if opt in bools:
                    get = self.cp.getboolean
                elif opt in floats:
                    get = self.cp.getfloat
                elif opt in ints:
                    get = self.cp.getint
                try:
                    val = get(sect, opt)
                except ValueError:
                    val = ''
                if is_ordered and '||' in val:
                    nam, val = val.split('||', 1)
                    opt = opt.strip()
                    val = nam, val.strip()
                thissect[opt] = val
            self.config[sect] = thissect

        if 'positions' in self.config:
            out = OrderedDict()
            poskeys = list(self.config['positions'].keys())
            poskeys.sort()
            for key in poskeys:
                name, val = self.config['positions'][key]
                name = name.strip()
                img, posval = val.strip().split('||')
                pos = [float(i) for i in posval.split(',')]
                out[name] = dict(image=img.strip(), position=pos)
            self.config['positions'] = out

        if 'stages' in self.config:
            out = OrderedDict()
            groups = []

            skeys = list(self.config['stages'].keys())
            skeys.sort()
            for key in skeys:
                name, val = self.config['stages'][key]
                name = normalize_pvname(name.strip())
                val = val.replace('||', ' | ')
                words = [w.strip() for w in val.split('|')]
                group = words[0]
                desc = words[1]
                if len(desc) == 0:
                    desc = None

                scale = 1.0
                if len(words) > 1 and len(words[2]) > 0:
                    scale = float(words[2])

                prec = None
                if len(words) > 2 and len(words[3]) > 0:
                    prec = int(words[3])

                maxstep = None
                if len(words) > 4 and len(words[4]) > 0:
                    maxstep = float(words[4])

                show = 1
                if len(words) > 5 and len(words[5]) > 0:
                    show = int(words[5])

                out[name] = dict(label=name,
                                 group=group,
                                 desc=desc,
                                 scale=scale,
                                 prec=prec,
                                 maxstep=maxstep,
                                 show=show)
                if group not in groups:
                    groups.append(group)
            self.config['stages'] = out
            self.config['stage_groups'] = groups
            self.nstages = len(out)

    def Save(self, fname=None, positions=None):
        o = []
        # print 'Save CONFIG FILE:', fname, os.getcwd()
        # print positions.keys()
        cnf = self.config

        if fname is not None:
            self.filename = fname
        o.append('## Sample Stage Configuration (saved: %s)' % (time.ctime()))

        if positions is None:
            positions = cnf['positions']
        for sect, optlist in conf_objs.items():
            o.append('#--------------------------#\n[%s]' % sect)
            if sect == 'positions' and positions is not None:
                o.append(POS_LEGEND)
                fmt = "%3.3i = %s || %s || %s "
                pfmt = ', '.join(['%f' for i in range(self.nstages)])
                idx = 1
                for name, val in positions.items():
                    pos = []
                    for pvname in cnf['stages']:
                        try:
                            pos.append(float(val['position'][pvname]))
                        except:
                            pass
                    pfmt = ', '.join(['%f' for i in range(len(pos))])
                    pos = pfmt % tuple(pos)
                    try:
                        tmpdir, imgfile = os.path.split(val['image'])
                    except:
                        tmpdir, imgfile = '', ''

                    o.append(fmt % (idx, name, imgfile, pos))
                    idx = idx + 1
            elif sect == 'stages':
                o.append(STAGE_LEGEND)
                fmt = "%i = %s || %s || %s || %s || %s || %s || %s"
                idx = 1
                for name, dat in cnf['stages'].items():
                    # print 'Save STAGE ', name, dat
                    # index =  motor || group   ||desc || scale || prec || maxstep || show
                    group = dat['group']
                    desc = dat['desc']
                    show = str(dat['show'])
                    scale = str(dat['scale'])
                    prec = str(dat['prec'])
                    maxstep = "%.3f" % (dat['maxstep'])
                    o.append(
                        fmt %
                        (idx, name, group, desc, scale, prec, maxstep, show))
                    idx = idx + 1
            if optlist is not None:
                for opt in optlist:
                    try:
                        val = cnf[sect].get(opt, ' ')
                        if not isinstance(val, (str, unicode)): val = str(val)
                        o.append("%s = %s" % (opt, val))
                    except:
                        pass
        o.append('#------------------#\n')
        # print 'Conf autosave ', fname
        # print os.path.abspath(fname)
        f = open(fname, 'w')
        f.write('\n'.join(o))
        f.close()

    def sections(self):
        return self.config.keys()

    def section(self, section):
        return self.config[section]

    def get(self, section, value=None):
        if value is None:
            return self.config[section]
        else:
            return self.config[section][value]
Ejemplo n.º 25
0
class PypiConfig(BaseConfig):
    """Wrapper around the pypi config file"""
    def __init__(self, config_filename=DIST_CONFIG_FILE, use_setup_cfg=True):
        """Grab the PyPI configuration.

        This is .pypirc in the home directory.  It is overridable for
        test purposes.

        If there is a setup.cfg file in the current directory, we read
        it too.
        """
        self.config_filename = config_filename
        self.use_setup_cfg = use_setup_cfg
        self.reload()

    def reload(self):
        """Load the config.

        Do the initial load of the config.

        Or reload it in case of problems: this is needed when a pypi
        upload fails, you edit the .pypirc file to fix the account
        settings, and tell release to retry the command.
        """
        self._read_configfile(use_setup_cfg=self.use_setup_cfg)

    def _read_configfile(self, use_setup_cfg=True):
        """Read the PyPI config file and store it (when valid).

        Usually read the setup.cfg too.
        """
        rc = self.config_filename
        if not os.path.isabs(rc):
            rc = os.path.join(os.path.expanduser('~'), self.config_filename)
        filenames = [rc]
        if use_setup_cfg:
            # If there is a setup.cfg in the package, parse it
            filenames.append('setup.cfg')
        files = [f for f in filenames if os.path.exists(f)]
        if not files:
            self.config = None
            return
        self.config = ConfigParser()
        self.config.read(files)

    def is_pypi_configured(self):
        # Do we have configuration for releasing to at least one
        # pypi-compatible server?
        if self.config is None:
            return False
        return len(self.distutils_servers()) > 0

    def get_server_config(self, server):
        """Get url, username, password for server.
        """
        repository_url = DEFAULT_REPOSITORY
        username = None
        password = None
        if self.config.has_section(server):
            if self.config.has_option(server, 'repository'):
                repository_url = self._get_text(server, 'repository')
            if self.config.has_option(server, 'username'):
                username = self._get_text(server, 'username')
            if self.config.has_option(server, 'password'):
                password = self._get_text(server, 'password', raw=True)
        if not username and self.config.has_option('server-login', 'username'):
            username = self._get_text('server-login', 'username')
        if not password and self.config.has_option('server-login', 'password'):
            password = self._get_text('server-login', 'password', raw=True)
        return {
            'repository_url': repository_url,
            'username': username,
            'password': password,
        }

    def distutils_servers(self):
        """Return a list of known distutils servers.

        If the config has an old pypi config, remove the default pypi
        server from the list.
        """
        try:
            index_servers = self._get_text('distutils',
                                           'index-servers',
                                           default='').split()
        except (NoSectionError, NoOptionError):
            index_servers = []
        if not index_servers:
            # If no distutils index-servers have been given, 'pypi' should be
            # the default.  This is what twine does.
            if self.config.has_option('server-login', 'username'):
                # We have a username, so upload to pypi should work fine, even
                # when no explicit pypi section is in the file.
                return ['pypi']
            # https://github.com/zestsoftware/zest.releaser/issues/199
            index_servers = ['pypi']
        # The servers all need to have a section in the config file.
        return [
            server for server in index_servers
            if self.config.has_section(server)
        ]

    def want_release(self):
        """Does the user normally want to release this package.

        Some colleagues find it irritating to have to remember to
        answer the question "Check out the tag (for tweaks or
        pypi/distutils server upload)" with the non-default 'no' when
        in 99 percent of the cases they just make a release specific
        for a customer, so they always answer 'no' here.  This is
        where an extra config option comes in handy: you can influence
        the default answer so you can just keep hitting 'Enter' until
        zest.releaser is done.

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want the default answer to this
        question to be 'no':

        [zest.releaser]
        release = no

        The default when this option has not been set is True.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        return self._get_boolean('zest.releaser', 'release', default=True)

    def extra_message(self):
        """Return extra text to be added to commit messages.

        This can for example be used to skip CI builds.  This at least
        works for Travis.  See
        http://docs.travis-ci.com/user/how-to-skip-a-build/

        Enable this mode by adding a ``extra-message`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            extra-message = [ci skip]
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self._get_text('zest.releaser',
                                    'extra-message',
                                    default=default)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def history_file(self):
        """Return path of history file.

        Usually zest.releaser can find the correct one on its own.
        But sometimes it may not find anything, or it finds multiple
        and selects the wrong one.

        Configure this by adding a ``history-file`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            history-file = deep/down/historie.doc
        """
        default = ''
        if self.config is None:
            return default
        marker = object()
        try:
            result = self._get_text('zest.releaser',
                                    'history-file',
                                    default=marker)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        if result == marker:
            # We were reading an underscore instead of a dash at first.
            try:
                result = self._get_text('zest.releaser',
                                        'history_file',
                                        default=default)
            except (NoSectionError, NoOptionError, ValueError):
                return default
        return result

    def encoding(self):
        """Return encoding to use for text files.

        Mostly the changelog and if needed `setup.py`.

        The encoding cannot always be determined correctly.
        This setting is a way to fix that.
        See https://github.com/zestsoftware/zest.releaser/issues/264

        Configure this by adding an ``encoding`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            encoding = utf-8
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self._get_text('zest.releaser',
                                    'encoding',
                                    default=default,
                                    raw=True)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def create_wheel(self):
        """Should we create a Python wheel for this package?

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want to create a Python wheel, next
        to a standard sdist:

        [zest.releaser]
        create-wheel = yes

        If there is no setting for ``create-wheel``, then if universal
        wheels are specified as in the following example, it is treated as if
        ``create-wheel`` was true:

        [bdist_wheel]
        universal = 1

        """
        if not USE_WHEEL:
            # If the wheel package is not available, we obviously
            # cannot create wheels.
            return False
        create_setting = self._get_boolean('zest.releaser', 'create-wheel',
                                           None)
        if create_setting is not None:
            # User specified this setting, it overrides
            # inferring from bdist_wheel
            return create_setting
        # No zest.releaser setting, are they asking for a universal wheel?
        # Then they want wheels in general.
        return self._get_boolean('bdist_wheel', 'universal')

    def register_package(self):
        """Should we try to register this package with a package server?

        For the standard Python Package Index (PyPI), registering a
        package is no longer needed: this is done automatically when
        uploading a distribution for a package.  In fact, trying to
        register may fail.  See
        https://github.com/zestsoftware/zest.releaser/issues/191
        So by default zest.releaser will no longer register a package.

        But you may be using your own package server, and registering
        may be wanted or even required there.  In this case
        you will need to turn on the register function.
        In your setup.cfg or ~/.pypirc, use the following to ensure that
        register is called on the package server:

        [zest.releaser]
        register = yes

        Note that if you have specified multiple package servers, this
        option is used for all of them.  There is no way to register and
        upload to server A, and only upload to server B.
        """
        return self._get_boolean('zest.releaser', 'register')

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.
        """
        return self._get_boolean('zest.releaser', 'no-input')

    def development_marker(self):
        """Return development marker to be appended in postrelease.

        Override the default ``.dev0`` in ~/.pypirc or setup.cfg using
        a ``development-marker`` option::

            [zest.releaser]
            development-marker = .dev1

        Returns default of ``.dev0`` when nothing has been configured.
        """
        default = '.dev0'
        if self.config is None:
            return default
        try:
            result = self._get_text('zest.releaser',
                                    'development-marker',
                                    default=default)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def push_changes(self):
        """Return whether the user wants to push the changes to the remote.

        Configure this mode by adding a ``push-changes`` option::

            [zest.releaser]
            push-changes = no

        The default when this option has not been set is True.
        """
        return self._get_boolean('zest.releaser', 'push-changes', default=True)

    def less_zeroes(self):
        """Return whether the user prefers less zeroes at the end of a version.

        Configure this mode by adding a ``less-zeroes`` option::

            [zest.releaser]
            less-zeroes = yes

        The default when this option has not been set is False.

        When set to true:
        - Instead of 1.3.0 we will suggest 1.3.
        - Instead of 2.0.0 we will suggest 2.0.

        This only makes sense for the bumpversion command.
        In the postrelease command we read this option too,
        but with the current logic it has no effect there.
        """
        return self._get_boolean('zest.releaser', 'less-zeroes')

    def version_levels(self):
        """How many levels does the user prefer in a version number?

        Configure this mode by adding a ``version-levels`` option::

            [zest.releaser]
            version-levels = 3

        The default when this option has not been set is 0, which means:
        no preference, so use the length of the current number.

        This means when suggesting a next version after 1.2:
        - with levels=0 we will suggest 1.3: no change
        - with levels=1 we will still suggest 1.3, as we will not
          use this to remove numbers, only to add them
        - with levels=2 we will suggest 1.3
        - with levels=3 we will suggest 1.2.1

        If the current version number has more levels, we keep them.
        So next version for 1.2.3.4 with levels=1 is 1.2.3.5.

        Tweaking version-levels and less-zeroes should give you the
        version number strategy that you prefer.
        """
        default = 0
        if self.config is None:
            return default
        try:
            result = self.config.getint('zest.releaser', 'version-levels')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        if result < 0:
            return default
        return result

    _tag_format_deprecated_message = "\n".join(line.strip() for line in """
    `tag-format` contains deprecated `%%(version)s` format. Please change to:

    [zest.releaser]
    tag-format = %s
    """.strip().splitlines())

    def tag_format(self, version):
        """Return the formatted tag that should be used in the release.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-format`` option::

            [zest.releaser]
            tag-format = v{version}

        ``tag-format`` must contain exaclty one formatting instruction: for the
        ``version`` key.

        Accepts also ``%(version)s`` format for backward compatibility.

        The default format, when nothing has been configured, is ``{version}``.
        """
        fmt = '{version}'
        if self.config is not None:
            try:
                fmt = self._get_text('zest.releaser',
                                     'tag-format',
                                     default=fmt,
                                     raw=True)
            except (NoSectionError, NoOptionError, ValueError):
                pass
        if '{version}' in fmt:
            return fmt.format(version=version)
        # BBB:
        if '%(version)s' in fmt:
            proposed_fmt = fmt.replace("%(version)s", "{version}")
            print(self._tag_format_deprecated_message % proposed_fmt)
            return fmt % {'version': version}
        print("{version} needs to be part of 'tag-format': %s" % fmt)
        sys.exit(1)

    def tag_message(self, version):
        """Return the commit message to be used when tagging.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-message``
        option::

            [zest.releaser]
            tag-message = Creating v{version} tag.

        ``tag-message`` must contain exaclty one formatting
        instruction: for the ``version`` key.

        The default format is ``Tagging {version}``.
        """
        fmt = 'Tagging {version}'
        if self.config:
            try:
                fmt = self._get_text('zest.releaser',
                                     'tag-message',
                                     default=fmt,
                                     raw=True)
            except (NoSectionError, NoOptionError, ValueError):
                pass
        if '{version}' not in fmt:
            print("{version} needs to be part of 'tag-message': '%s'" % fmt)
            sys.exit(1)
        return fmt.format(version=version)

    def tag_signing(self):
        """Return whether the tag should be signed.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-signing`` option::

            [zest.releaser]
            tag-signing = yes

        ``tag-signing`` must contain exaclty one word which will be
        converted to a boolean. Currently are accepted (case
        insensitively): 0, false, no, off for False, and 1, true, yes,
        on for True).

        The default when this option has not been set is False.

        """
        return self._get_boolean('zest.releaser', 'tag-signing', default=False)

    def date_format(self):
        """Return the string format for the date used in the changelog.

        Override the default ``%Y-%m-%d`` in ~/.pypirc or setup.cfg using
        a ``date-format`` option::

            [zest.releaser]
            date-format = %%B %%e, %%Y

        Note: the % signs should be doubled for compatibility with other tools
        (i.e. pip) that parse setup.cfg using the interpolating ConfigParser.

        Returns default of ``%Y-%m-%d`` when nothing has been configured.
        """
        default = '%Y-%m-%d'
        if self.config is None:
            return default
        try:
            result = self._get_text('zest.releaser',
                                    'date-format',
                                    default=default).replace('%%', '%')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 26
0
class StationConfig(object):
    #  sections            name      ordered?
    __sects = OrderedDict((('setup',       False),
                           ('server',   False),
                           ('positioners', True),
                           ('detectors',   True),
                           ('counters',    True),
                           ('xafs',        False),
                           ('slewscan',    False),
                           ('slewscan_positioners',  True),
                           ('extrapvs',   True),
                           ))

    def __init__(self, filename=None, text=None):
        for s in self.__sects:
           setattr(self, s, {})

        self._cp = ConfigParser()
        if filename is None:
            filename = DEF_CONFFILE
        self.filename = filename
        # print 'StationConfig ', filename, os.path.abspath(filename)
        # print os.path.exists(filename),   os.path.isfile(filename)
        if (os.path.exists(filename) and
            os.path.isfile(filename)):
            ret = self._cp.read(filename)
            if len(ret) == 0:
                time.sleep(0.1)
                self._cp.read(filename)
        else:
            self._cp.readfp(StringIO(DEFAULT_CONF))
        self.Read()

    def Read(self, filename=None):
        "read config"
        if (filename is not None and
            (os.path.exists(filename) and
             os.path.isfile(filename))):
            ret = self._cp.read(filename)
            if len(ret) == 0:
                time.sleep(0.1)
                self._cp.read(filename)
            self.filename = filename

        # process sections
        for sect, ordered in self.__sects.items():
            if not self._cp.has_section(sect):
                continue
            thissect = {}
            opt_keys = self._cp.options(sect)
            if ordered:
                thissect = OrderedDict()
                opt_keys.sort()
            for opt in opt_keys:
                val = self._cp.get(sect, opt)
                if '||' in val:
                    words = [i.strip() for i in val.split('||')]
                    label = words.pop(0)
                    if len(words) == 1:
                        words = words[0]
                    else:
                        tmp = []
                        for w in words:
                            if ',' in w and '=' in w:
                                tmp.append(opts2dict(w))
                            else:
                                tmp.append(w)
                        words = tuple(tmp)
                    thissect[label] = words
                else:
                    thissect[opt] = val
                setattr(self, sect, thissect)
        for key, val in self.positioners.items():
            fi = []
            if isinstance(val, (list, tuple)):
                for v in val:
                    if '.' not in v: v = '%s.VAL' % v
                    fi.append(v)
            else:
                if '.' not in val:
                    val = '%s.VAL' % val
                fi = [val, val]
            self.positioners[key] = tuple(fi)

    def Save(self, fname=None):
        "save config file"
        if fname is not None:
            self.filename = fname
        if fname is None:
            fname = self.filename = DEF_CONFFILE
            path, fn = os.path.split(fname)
            if not os.path.exists(path):
                os.makedirs(path, mode=0o755)

        out = ['### %s: %s' % (TITLE, get_timestamp())]
        for sect, ordered in self.__sects.items():
            out.append('#------------------------------#\n[%s]' % sect)
            if sect in ('setup', 'server', 'slewscan', 'xafs'):
                for name, val in self.setup.items():
                    out.append("%s = %s" % (name, val))
            elif sect == 'detectors':
                out.append(DET_LEGEND)
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        wout = []
                        for w in val:
                            if isinstance(w, dict):
                                wout.append(dict2opts(w))
                            elif isinstance(w, (str, unicode)):
                                wout.append(w)
                            else:
                                wout.append(repr(w))
                        val = ' || '.join(wout)
                    out.append("%i = %s || %s"  % (idx, key, val))

            else:
                leg = LEGEND
                out.append(LEGEND)
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        val = ' || '.join(val)
                    out.append("%i = %s || %s"  % (idx, key, val))
        out.append('#-----------------------#')
        f = open(fname, 'w')
        f.write('\n'.join(out))
        f.close()

    def sections(self):
        return self.__sects.keys()
Ejemplo n.º 27
0
class Configuration(object):
    defaults = {}

    def __init__(self, filename=None):
        self._config = ConfigParser()
        self._set_defaults()
        self._state_drivers = {}
        if filename is not None:
            self.load(filename)

    def _set_defaults(self):
        """Set defaults for config
        """
        self._config.add_section('main')
        for key, value in six.iteritems(self.defaults):
            if isinstance(value, dict):
                self._config.add_section(key)
                for subkey, subvalue in six.iteritems(value):
                    self._config.set(key, subkey, subvalue)
            else:
                self._config.set('main', key, value)

    def load(self, filename):
        """Load the configuration by filename
        """
        self._config.read(filename)

    def save(self, filename):
        """Save the configuration to a file
        """
        with open(filename, 'w') as handle:
            self._config.write(handle)

    @staticmethod
    def sanitize(items):
        options = {}
        for key, value in items:
            if key.endswith('[int]'):
                options[key[:-5]] = int(value)
            elif key.endswith('[bool]'):
                value = value.lower()
                if value in BOOL_MAP[True]:
                    value = True
                elif value in BOOL_MAP[False]:
                    value = False
                else:
                    raise ValueError('Expected boolean for {}'.format(key))
                options[key[:-6]] = value
            else:
                options[key] = value
        return options

    def __getitem__(self, name):
        if self._config.has_section(name):
            return self.sanitize(self._config.items(name))
        elif name == 'main':
            raise ValueError('Missing main section of configuration')
        return self['main'][name]

    def state_driver(self, name='ai'):
        """Get an instance of the state driver
        """
        from database import state

        if name not in self._state_drivers:
            extras = self[name]
            driver = extras.pop('state-driver')
            if driver == 'redis':
                self._state_drivers[name] = state.RedisDriver(self, extras)
            elif driver == 'dict':
                self._state_drivers[name] = state.MemoryDriver(self, extras)
            else:
                raise ValueError('Unknown state driver')
        return self._state_drivers[name]
Ejemplo n.º 28
0
class SetupConfig(object):
    """Wrapper around the setup.cfg file if available.

    One reason is to cleanup setup.cfg from these settings::

        [egg_info]
        tag_build = dev
        tag_svn_revision = true

    Another is for optional zest.releaser-specific settings::

        [zest.releaser]
        python-file-with-version = reinout/maurits.py


    """

    config_filename = SETUP_CONFIG_FILE

    def __init__(self):
        """Grab the configuration (overridable for test purposes)"""
        # If there is a setup.cfg in the package, parse it
        if not os.path.exists(self.config_filename):
            self.config = None
            return
        self.config = ConfigParser()
        with codecs.open(self.config_filename, 'r', 'utf8') as fp:
            self.config.readfp(fp)

    def development_marker(self):
        """Return development marker to be appended in postrelease

        Override the default ``.dev0`` in setup.cfg using
        a ``development-marker`` option::

            [zest.releaser]
            development-marker = .dev1

        Returns default of `.dev0` when nothing has been configured.

        """
        try:
            result = self.config.get('zest.releaser',
                                     'development-marker')
        except (NoSectionError, NoOptionError, ValueError):
            result = ".dev0"
        return result

    def has_bad_commands(self):
        if self.config is None:
            return False
        if not self.config.has_section('egg_info'):
            # bail out early as the main section is not there
            return False
        bad = False
        # Check 1.
        if self.config.has_option('egg_info', 'tag_build'):
            # Might still be empty.
            value = self.config.get('egg_info', 'tag_build')
            if value:
                logger.warn("%s has [egg_info] tag_build set to %r",
                            self.config_filename, value)
                bad = True
        # Check 2.
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            if self.config.getboolean('egg_info', 'tag_svn_revision'):
                value = self.config.get('egg_info', 'tag_svn_revision')
                logger.warn("%s has [egg_info] tag_svn_revision set to %r",
                            self.config_filename, value)
                bad = True
        return bad

    def fix_config(self):
        if not self.has_bad_commands():
            logger.warn("Cannot fix already fine %s.", self.config_filename)
            return
        if self.config.has_option('egg_info', 'tag_build'):
            self.config.set('egg_info', 'tag_build', '')
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            self.config.set('egg_info', 'tag_svn_revision', 'false')
        new_setup = open(self.config_filename, 'w')
        try:
            self.config.write(new_setup)
        finally:
            new_setup.close()
        logger.info("New setup.cfg contents:")
        print(''.join(open(self.config_filename).readlines()))

    def python_file_with_version(self):
        """Return Python filename with ``__version__`` marker, if configured.

        Enable this by adding a ``python-file-with-version`` option::

            [zest.releaser]
            python-file-with-version = reinout/maurits.py

        Return None when nothing has been configured.

        """
        default = None
        if self.config is None:
            return default
        try:
            result = self.config.get(
                'zest.releaser',
                'python-file-with-version')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 29
0
class SetupConfig(object):
    """Wrapper around the setup.cfg file if available.

    One reason is to cleanup setup.cfg from these settings::

        [egg_info]
        tag_build = dev
        tag_svn_revision = true

    Another is for optional zest.releaser-specific settings::

        [zest.releaser]
        python-file-with-version = reinout/maurits.py


    """

    config_filename = SETUP_CONFIG_FILE

    def __init__(self):
        """Grab the configuration (overridable for test purposes)"""
        # If there is a setup.cfg in the package, parse it
        if not os.path.exists(self.config_filename):
            self.config = None
            return
        self.config = ConfigParser()
        with codecs.open(self.config_filename, 'r', 'utf8') as fp:
            self.config.readfp(fp)

    def has_bad_commands(self):
        if self.config is None:
            return False
        if not self.config.has_section('egg_info'):
            # bail out early as the main section is not there
            return False
        bad = False
        # Check 1.
        if self.config.has_option('egg_info', 'tag_build'):
            # Might still be empty.
            value = self.config.get('egg_info', 'tag_build')
            if value:
                logger.warn("%s has [egg_info] tag_build set to %r",
                            self.config_filename, value)
                bad = True
        # Check 2.
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            if self.config.getboolean('egg_info', 'tag_svn_revision'):
                value = self.config.get('egg_info', 'tag_svn_revision')
                logger.warn("%s has [egg_info] tag_svn_revision set to %r",
                            self.config_filename, value)
                bad = True
        return bad

    def fix_config(self):
        if not self.has_bad_commands():
            logger.warn("Cannot fix already fine %s.", self.config_filename)
            return
        if self.config.has_option('egg_info', 'tag_build'):
            self.config.set('egg_info', 'tag_build', '')
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            self.config.set('egg_info', 'tag_svn_revision', 'false')
        new_setup = open(self.config_filename, 'w')
        try:
            self.config.write(new_setup)
        finally:
            new_setup.close()
        logger.info("New setup.cfg contents:")
        print(''.join(open(self.config_filename).readlines()))

    def python_file_with_version(self):
        """Return Python filename with ``__version__`` marker, if configured.

        Enable this by adding a ``python-file-with-version`` option::

            [zest.releaser]
            python-file-with-version = reinout/maurits.py

        Return None when nothing has been configured.

        """
        default = None
        if self.config is None:
            return default
        try:
            result = self.config.get('zest.releaser',
                                     'python-file-with-version')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 30
0
class SHOUTcasterFavorites:
    configfile = "/etc/NETcaster.conf"

    def __init__(self):
        self.configparser = ConfigParser()
        self.configparser.read(self.configfile)

    def getStreams(self):
        streams = []
        sections = self.configparser.sections()
        print(sections)
        for section in sections:
            stream = self.getStreamByName(section)
            streams.append(stream)
        return streams

    def isStream(self, streamname):
        if self.configparser.has_section(streamname) is True:
            return True
        else:
            return False

    def getStreamByName(self, streamname):
        print("[" + myname + "] load " + streamname + " from config")
        if self.isStream(streamname) is True:
            stream = Stream(streamname,
                            self.configparser.get(streamname, "description"),
                            self.configparser.get(streamname, "url"),
                            type=self.configparser.get(streamname, "type"))
            stream.setFavorite(True)
            return stream
        else:
            return False

    def addStream(self, stream):
        print("[" + myname + "] adding " + stream.getName() + " to config")
        try:
            self.configparser.add_section(stream.getName())
        except DuplicateSectionError as e:
            print("[" + myname + "] error while adding stream to config:", e)
            return False, e
        else:
            # XXX: I hope this still works properly if we make a optimistic
            # return here since otherwise the interface would need to be changed
            # to work with a callback
            stream.getURL(boundFunction(self.addStreamCb, stream))
            return True, "Stream added"

    def addStreamCb(self, stream, url=None):
        self.configparser.set(stream.getName(), "description",
                              stream.getDescription())
        self.configparser.set(stream.getName(), "url", url)
        self.configparser.set(stream.getName(), "type", stream.getType())
        self.writeConfig()

    def changeStream(self, streamold, streamnew):
        if self.configparser.has_section(streamold.getName()) is False:
            return False, "stream not found in config"
        elif self.configparser.has_section(streamnew.getName()) is True:
            return False, "stream with that name exists already"
        else:
            self.configparser.remove_section(streamold.getName())
            return self.addStream(streamnew)

    def deleteStreamWithName(self, streamname):
        self.configparser.remove_section(streamname)
        self.writeConfig()

    def writeConfig(self):
        print("[" + myname + "] writing config to " + self.configfile)

        fp = open(self.configfile, "w")
        self.configparser.write(fp)
        fp.close()
Ejemplo n.º 31
0
class PypiConfig(object):
    """Wrapper around the pypi config file"""

    def __init__(self, config_filename=DIST_CONFIG_FILE, use_setup_cfg=True):
        """Grab the PyPI configuration.

        This is .pypirc in the home directory.  It is overridable for
        test purposes.

        If there is a setup.cfg file in the current directory, we read
        it too.
        """
        self.config_filename = config_filename
        self._read_configfile(use_setup_cfg=use_setup_cfg)

    def _read_configfile(self, use_setup_cfg=True):
        """Read the PyPI config file and store it (when valid).

        Usually read the setup.cfg too.
        """
        rc = self.config_filename
        if not os.path.isabs(rc):
            rc = os.path.join(os.path.expanduser('~'), self.config_filename)
        filenames = [rc]
        if use_setup_cfg:
            # If there is a setup.cfg in the package, parse it
            filenames.append('setup.cfg')
        files = [f for f in filenames if os.path.exists(f)]
        if not files:
            self.config = None
            return
        self.config = ConfigParser()
        for filename in files:
            with codecs.open(filename, 'r', 'utf8') as fp:
                self.config.readfp(fp)

    def is_pypi_configured(self):
        # Do we have configuration for releasing to at least one
        # pypi-compatible server?
        if self.config is None:
            return False
        if self.is_old_pypi_config():
            return True
        if self.is_new_pypi_config() and len(self.distutils_servers()) > 0:
            return True
        return False

    def is_old_pypi_config(self):
        if self.config is None:
            return False
        try:
            self.config.get('server-login', 'username')
        except (NoSectionError, NoOptionError):
            return False
        return True

    def is_new_pypi_config(self):
        try:
            self.config.get('distutils', 'index-servers')
        except (NoSectionError, NoOptionError):
            return False
        return True

    def get_server_config(self, server):
        """Get url, username, password for server.
        """
        repository_url = DEFAULT_REPOSITORY
        username = None
        password = None
        if self.config.has_section(server):
            if self.config.has_option(server, 'repository'):
                repository_url = self.config.get(server, 'repository')
            if self.config.has_option(server, 'username'):
                username = self.config.get(server, 'username')
            if self.config.has_option(server, 'password'):
                password = self.config.get(server, 'password')
        if not username and self.config.has_option('server-login', 'username'):
            username = self.config.get('server-login', 'username')
        if not password and self.config.has_option('server-login', 'password'):
            password = self.config.get('server-login', 'password')
        return {
            'repository_url': repository_url,
            'username': username,
            'password': password,
        }

    def distutils_servers(self):
        """Return a list of known distutils servers.

        If the config has an old pypi config, remove the default pypi
        server from the list.
        """
        try:
            raw_index_servers = self.config.get('distutils', 'index-servers')
        except (NoSectionError, NoOptionError):
            return []
        ignore_servers = ['']
        if self.is_old_pypi_config():
            # We have already asked about uploading to pypi using the normal
            # upload.
            ignore_servers.append('pypi')
            # Yes, you can even have an old pypi config with a
            # [distutils] server list.
        index_servers = [
            server.strip() for server in raw_index_servers.split('\n')
            if server.strip() not in ignore_servers]
        return index_servers

    def want_release(self):
        """Does the user normally want to release this package.

        Some colleagues find it irritating to have to remember to
        answer the question "Check out the tag (for tweaks or
        pypi/distutils server upload)" with the non-default 'no' when
        in 99 percent of the cases they just make a release specific
        for a customer, so they always answer 'no' here.  This is
        where an extra config option comes in handy: you can influence
        the default answer so you can just keep hitting 'Enter' until
        zest.releaser is done.

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want the default answer to this
        question to be 'no':

        [zest.releaser]
        release = no

        The default when this option has not been set is True.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        default = True
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'release')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def extra_message(self):
        """Return extra text to be added to commit messages.

        This can for example be used to skip CI builds.  This at least
        works for Travis.  See
        http://docs.travis-ci.com/user/how-to-skip-a-build/

        Enable this mode by adding a ``extra-message`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            extra-message = [ci skip]
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self.config.get('zest.releaser', 'extra-message')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def create_wheel(self):
        """Should we create a Python wheel for this package?

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want to create a Python wheel, next
        to a standard sdist:

        [zest.releaser]
        create-wheel = yes

        """
        if not USE_WHEEL:
            # If the wheel package is not available, we obviously
            # cannot create wheels.
            return False
        default = False
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'create-wheel')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        default = False
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'no-input')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 32
0
class PypiConfig(BaseConfig):
    """Wrapper around the pypi config file"""

    def __init__(self, config_filename=DIST_CONFIG_FILE, use_setup_cfg=True):
        """Grab the PyPI configuration.

        This is .pypirc in the home directory.  It is overridable for
        test purposes.

        If there is a setup.cfg file in the current directory, we read
        it too.
        """
        self.config_filename = config_filename
        self.use_setup_cfg = use_setup_cfg
        self.reload()

    def reload(self):
        """Load the config.

        Do the initial load of the config.

        Or reload it in case of problems: this is needed when a pypi
        upload fails, you edit the .pypirc file to fix the account
        settings, and tell release to retry the command.
        """
        self._read_configfile(use_setup_cfg=self.use_setup_cfg)

    def _read_configfile(self, use_setup_cfg=True):
        """Read the PyPI config file and store it (when valid).

        Usually read the setup.cfg too.
        """
        rc = self.config_filename
        if not os.path.isabs(rc):
            rc = os.path.join(os.path.expanduser('~'), self.config_filename)
        filenames = [rc]
        if use_setup_cfg:
            # If there is a setup.cfg in the package, parse it
            filenames.append('setup.cfg')
        files = [f for f in filenames if os.path.exists(f)]
        if not files:
            self.config = None
            return
        self.config = ConfigParser()
        self.config.read(files)

    def is_pypi_configured(self):
        # Do we have configuration for releasing to at least one
        # pypi-compatible server?
        if self.config is None:
            return False
        return len(self.distutils_servers()) > 0

    def distutils_servers(self):
        """Return a list of known distutils servers.

        If the config has an old pypi config, remove the default pypi
        server from the list.
        """
        try:
            index_servers = self._get_text(
                'distutils', 'index-servers', default='').split()
        except (NoSectionError, NoOptionError):
            index_servers = []
        if not index_servers:
            # If no distutils index-servers have been given, 'pypi' should be
            # the default.  This is what twine does.
            if self.config.has_option('server-login', 'username'):
                # We have a username, so upload to pypi should work fine, even
                # when no explicit pypi section is in the file.
                return ['pypi']
            # https://github.com/zestsoftware/zest.releaser/issues/199
            index_servers = ['pypi']
        # The servers all need to have a section in the config file.
        return [server for server in index_servers
                if self.config.has_section(server)]

    def want_release(self):
        """Does the user normally want to release this package.

        Some colleagues find it irritating to have to remember to
        answer the question "Check out the tag (for tweaks or
        pypi/distutils server upload)" with the non-default 'no' when
        in 99 percent of the cases they just make a release specific
        for a customer, so they always answer 'no' here.  This is
        where an extra config option comes in handy: you can influence
        the default answer so you can just keep hitting 'Enter' until
        zest.releaser is done.

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want the default answer to this
        question to be 'no':

        [zest.releaser]
        release = no

        The default when this option has not been set is True.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        return self._get_boolean('zest.releaser', 'release', default=True)

    def extra_message(self):
        """Return extra text to be added to commit messages.

        This can for example be used to skip CI builds.  This at least
        works for Travis.  See
        http://docs.travis-ci.com/user/how-to-skip-a-build/

        Enable this mode by adding a ``extra-message`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            extra-message = [ci skip]
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self._get_text(
                'zest.releaser', 'extra-message', default=default)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def history_file(self):
        """Return path of history file.

        Usually zest.releaser can find the correct one on its own.
        But sometimes it may not find anything, or it finds multiple
        and selects the wrong one.

        Configure this by adding a ``history-file`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            history-file = deep/down/historie.doc
        """
        default = ''
        if self.config is None:
            return default
        marker = object()
        try:
            result = self._get_text(
                'zest.releaser', 'history-file', default=marker)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        if result == marker:
            # We were reading an underscore instead of a dash at first.
            try:
                result = self._get_text(
                    'zest.releaser', 'history_file', default=default)
            except (NoSectionError, NoOptionError, ValueError):
                return default
        return result

    def encoding(self):
        """Return encoding to use for text files.

        Mostly the changelog and if needed `setup.py`.

        The encoding cannot always be determined correctly.
        This setting is a way to fix that.
        See https://github.com/zestsoftware/zest.releaser/issues/264

        Configure this by adding an ``encoding`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            encoding = utf-8
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self._get_text(
                'zest.releaser', 'encoding', default=default, raw=True)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def create_wheel(self):
        """Should we create a Python wheel for this package?

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want to create a Python wheel, next
        to a standard sdist:

        [zest.releaser]
        create-wheel = yes

        If there is no setting for ``create-wheel``, then if there is a
        ``[bdist_wheel]`` section, it is treated as if
        ``create-wheel`` was true.  We used to look at the value of
        the ``universal`` option, but that no longer matters.
        This will still create a wheel:

        [bdist_wheel]
        universal = 0

        See https://github.com/zestsoftware/zest.releaser/issues/315
        """
        if not USE_WHEEL:
            # If the wheel package is not available, we obviously
            # cannot create wheels.
            return False
        create_setting = self._get_boolean(
            'zest.releaser', 'create-wheel', None)
        if create_setting is not None:
            # User specified this setting, it overrides
            # inferring from bdist_wheel
            return create_setting
        # No zest.releaser setting, are they asking for a universal wheel?
        # Then they want wheels in general.
        return self.config.has_section('bdist_wheel')

    def register_package(self):
        """Should we try to register this package with a package server?

        For the standard Python Package Index (PyPI), registering a
        package is no longer needed: this is done automatically when
        uploading a distribution for a package.  In fact, trying to
        register may fail.  See
        https://github.com/zestsoftware/zest.releaser/issues/191
        So by default zest.releaser will no longer register a package.

        But you may be using your own package server, and registering
        may be wanted or even required there.  In this case
        you will need to turn on the register function.
        In your setup.cfg or ~/.pypirc, use the following to ensure that
        register is called on the package server:

        [zest.releaser]
        register = yes

        Note that if you have specified multiple package servers, this
        option is used for all of them.  There is no way to register and
        upload to server A, and only upload to server B.
        """
        return self._get_boolean('zest.releaser', 'register')

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.
        """
        return self._get_boolean('zest.releaser', 'no-input')

    def development_marker(self):
        """Return development marker to be appended in postrelease.

        Override the default ``.dev0`` in ~/.pypirc or setup.cfg using
        a ``development-marker`` option::

            [zest.releaser]
            development-marker = .dev1

        Returns default of ``.dev0`` when nothing has been configured.
        """
        default = '.dev0'
        if self.config is None:
            return default
        try:
            result = self._get_text(
                'zest.releaser', 'development-marker', default=default)
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def push_changes(self):
        """Return whether the user wants to push the changes to the remote.

        Configure this mode by adding a ``push-changes`` option::

            [zest.releaser]
            push-changes = no

        The default when this option has not been set is True.
        """
        return self._get_boolean('zest.releaser', 'push-changes', default=True)

    def less_zeroes(self):
        """Return whether the user prefers less zeroes at the end of a version.

        Configure this mode by adding a ``less-zeroes`` option::

            [zest.releaser]
            less-zeroes = yes

        The default when this option has not been set is False.

        When set to true:
        - Instead of 1.3.0 we will suggest 1.3.
        - Instead of 2.0.0 we will suggest 2.0.

        This only makes sense for the bumpversion command.
        In the postrelease command we read this option too,
        but with the current logic it has no effect there.
        """
        return self._get_boolean('zest.releaser', 'less-zeroes')

    def version_levels(self):
        """How many levels does the user prefer in a version number?

        Configure this mode by adding a ``version-levels`` option::

            [zest.releaser]
            version-levels = 3

        The default when this option has not been set is 0, which means:
        no preference, so use the length of the current number.

        This means when suggesting a next version after 1.2:
        - with levels=0 we will suggest 1.3: no change
        - with levels=1 we will still suggest 1.3, as we will not
          use this to remove numbers, only to add them
        - with levels=2 we will suggest 1.3
        - with levels=3 we will suggest 1.2.1

        If the current version number has more levels, we keep them.
        So next version for 1.2.3.4 with levels=1 is 1.2.3.5.

        Tweaking version-levels and less-zeroes should give you the
        version number strategy that you prefer.
        """
        default = 0
        if self.config is None:
            return default
        try:
            result = self.config.getint('zest.releaser', 'version-levels')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        if result < 0:
            return default
        return result

    _tag_format_deprecated_message = "\n".join(line.strip() for line in """
    `tag-format` contains deprecated `%%(version)s` format. Please change to:

    [zest.releaser]
    tag-format = %s
    """.strip().splitlines())

    def tag_format(self, version):
        """Return the formatted tag that should be used in the release.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-format`` option::

            [zest.releaser]
            tag-format = v{version}

        ``tag-format`` must contain exaclty one formatting instruction: for the
        ``version`` key.

        Accepts also ``%(version)s`` format for backward compatibility.

        The default format, when nothing has been configured, is ``{version}``.
        """
        fmt = '{version}'
        if self.config is not None:
            try:
                fmt = self._get_text(
                    'zest.releaser', 'tag-format', default=fmt, raw=True)
            except (NoSectionError, NoOptionError, ValueError):
                pass
        if '{version}' in fmt:
            return fmt.format(version=version)
        # BBB:
        if '%(version)s' in fmt:
            proposed_fmt = fmt.replace("%(version)s", "{version}")
            print(self._tag_format_deprecated_message % proposed_fmt)
            return fmt % {'version': version}
        print("{version} needs to be part of 'tag-format': %s" % fmt)
        sys.exit(1)

    def tag_message(self, version):
        """Return the commit message to be used when tagging.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-message``
        option::

            [zest.releaser]
            tag-message = Creating v{version} tag.

        ``tag-message`` must contain exaclty one formatting
        instruction: for the ``version`` key.

        The default format is ``Tagging {version}``.
        """
        fmt = 'Tagging {version}'
        if self.config:
            try:
                fmt = self._get_text(
                    'zest.releaser', 'tag-message', default=fmt, raw=True)
            except (NoSectionError, NoOptionError, ValueError):
                pass
        if '{version}' not in fmt:
            print("{version} needs to be part of 'tag-message': '%s'" % fmt)
            sys.exit(1)
        return fmt.format(version=version)

    def tag_signing(self):
        """Return whether the tag should be signed.

        Configure it in ~/.pypirc or setup.cfg using a ``tag-signing`` option::

            [zest.releaser]
            tag-signing = yes

        ``tag-signing`` must contain exaclty one word which will be
        converted to a boolean. Currently are accepted (case
        insensitively): 0, false, no, off for False, and 1, true, yes,
        on for True).

        The default when this option has not been set is False.

        """
        return self._get_boolean('zest.releaser', 'tag-signing', default=False)

    def date_format(self):
        """Return the string format for the date used in the changelog.

        Override the default ``%Y-%m-%d`` in ~/.pypirc or setup.cfg using
        a ``date-format`` option::

            [zest.releaser]
            date-format = %%B %%e, %%Y

        Note: the % signs should be doubled for compatibility with other tools
        (i.e. pip) that parse setup.cfg using the interpolating ConfigParser.

        Returns default of ``%Y-%m-%d`` when nothing has been configured.
        """
        default = '%Y-%m-%d'
        if self.config is None:
            return default
        try:
            result = self._get_text(
                'zest.releaser', 'date-format', default=default
            ).replace('%%', '%')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 33
0
def load(cfg_file=None, environment=None, overrides=None):
    """
    Load configuration.

    A configuration file consists of sections, led by a ``[section]`` header
    and followed by ``name: value`` entries. Lines beginning with ``'#'`` are
    ignored and may be used to provide comments.

    A configuration file can contain multiple sections. The configuration
    object is populated with values from the ``global`` section and additional
    sections based on the fully qualified domain name of the local host. For
    example, on the host ``tin.eqiad.wmnet`` the final value for a given
    setting would be the first value found in sections: ``tin.eqiad.wmnet``,
    ``eqiad.wmnet``, ``wmnet`` or ``global``. Sections not present in the
    configuration file will be ignored.

    Configuration values are loaded from a file specified by the ``-c`` or
    ``--conf`` command-line options or from the default locations with the
    following hierarchy, sorted by override priority:

    #. ``$(pwd)/scap/environments/<environment>/scap.cfg`` or
       ``$(pwd)/scap/scap.cfg`` (if no environment was specified)
    #. ``/etc/scap.cfg``

    For example, if a configuration parameter is set in
    ``$(pwd)/scap/scap.cfg`` and that same parameter is set in
    ``/etc/scap.cfg`` the value for that parameter set in
    ``$(pwd)/scap/scap.cfg`` will be used during execution.

    :param cfg_file: Alternate configuration file
    :param environment: the string path under which scap.cfg is found
    :param overrides: Dict of configuration values
    :returns: dict of configuration values
    """
    local_cfg = os.path.join(os.getcwd(), 'scap')

    parser = ConfigParser()
    if cfg_file:
        try:
            cfg_file = open(cfg_file)
        except TypeError:
            # Assume that cfg_file is already an open file
            pass

        parser.readfp(cfg_file)
    else:
        parser.read([
            '/etc/scap.cfg',
            os.path.join(local_cfg, 'scap.cfg'),
            utils.get_env_specific_filename(
                os.path.join(local_cfg, 'scap.cfg'),
                environment
            )
        ])

    fqdn = socket.getfqdn().split('.')
    sections = ['global']
    sections += ['.'.join(fqdn[l:]) for l in range(0, len(fqdn))][::-1]

    config = {key: value for key, (_, value) in DEFAULT_CONFIG.items()}

    for section in sections:
        if parser.has_section(section):
            # Do not interpolate items in the section.
            # Fixes crash on tin: 'int' object has no attribute 'find'
            for key, value in parser.items(section, True):
                config[key] = coerce_value(key, value)

    config = override_config(config, overrides)

    if not environment and config.get('environment', None):
        return load(cfg_file, config.get('environment'), overrides)

    config['environment'] = environment
    return config
Ejemplo n.º 34
0
class StageConfig(object):
    def __init__(self, filename=None, text=None):
        self.config = {}
        self.cp = ConfigParser()
        self.nstages = 0
        fname = None
        if filename is not None and os.path.exists(filename):
            fname = filename
        if fname is None:
            for filename in conf_files:
                if os.path.exists(filename) and os.path.isfile(filename):
                    fname = filename
                    break

        if fname is not None:
            self.Read(fname=fname)
        else:
            self.cp.readfp(StringIO(DEFAULT_CONF))
            self._process_data()

    def Read(self,fname=None):
        if fname is not None:
            ret = self.cp.read(fname)
            if len(ret)==0:
                time.sleep(0.5)
                ret = self.cp.read(fname)
            self.filename = fname
            self._process_data()

            stage_names = self.config['stages']
            image_folder = self.config['camera']['image_folder']
            pos = OrderedDict()
            if 'positions' not in self.config:
                self.config['positions'] = {}
            for key, dat in self.config['positions'].items():
                img_fname = dat['image']
                image = {'type': 'filename',
                         'data': os.path.join(image_folder, img_fname)}

                poslist = dat['position']
                posdict = {}
                for name, val in zip(stage_names, poslist):
                    posdict[name] = val
                pos[key] = dict(image=image, position=posdict)
            self.config['positions'] = pos

    def _process_data(self):
        for sect, opts in conf_sects.items():
            if not self.cp.has_section(sect):
                # print 'skipping section ' ,sect
                continue
            bools = opts.get('bools',[])
            floats= opts.get('floats',[])
            ints  = opts.get('ints',[])
            thissect = {}
            is_ordered = False
            if 'ordered' in opts:
                is_ordered = True

            for opt in self.cp.options(sect):
                get = self.cp.get
                if opt in bools:
                    get = self.cp.getboolean
                elif opt in floats:
                    get = self.cp.getfloat
                elif opt in ints:
                    get = self.cp.getint
                try:
                    val = get(sect, opt)
                except ValueError:
                    val = ''
                if is_ordered and '||' in val:
                    nam, val = val.split('||', 1)
                    opt = opt.strip()
                    val = nam, val.strip()
                thissect[opt] = val
            self.config[sect] = thissect

        if 'positions' in self.config:
            out = OrderedDict()
            poskeys = list(self.config['positions'].keys())
            poskeys.sort()
            for key in poskeys:
                name, val = self.config['positions'][key]
                name = name.strip()
                img, posval = val.strip().split('||')
                pos = [float(i) for i in posval.split(',')]
                out[name] = dict(image=img.strip(), position= pos)
            self.config['positions'] = out

        if 'stages' in self.config:
            out = OrderedDict()
            groups = []

            skeys = list(self.config['stages'].keys())
            skeys.sort()
            for key in skeys:
                name, val = self.config['stages'][key]
                name = normalize_pvname(name.strip())
                val = val.replace('||', ' | ')
                words = [w.strip() for w in val.split('|')]
                group = words[0]
                desc  = words[1]
                if len(desc) == 0:
                    desc = None

                scale = 1.0
                if len(words) > 1 and len(words[2]) > 0:
                    scale = float(words[2])

                prec = None
                if len(words) > 2 and len(words[3]) > 0:
                    prec = int(words[3])

                maxstep = None
                if len(words) > 4 and len(words[4]) > 0:
                    maxstep = float(words[4])

                show = 1
                if len(words) > 5 and len(words[5]) > 0:
                    show = int(words[5])

                out[name] = dict(label=name, group=group, desc=desc, scale=scale,
                                 prec=prec, maxstep=maxstep, show=show)
                if group not in groups:
                    groups.append(group)
            self.config['stages'] = out
            self.config['stage_groups'] = groups
            self.nstages = len(out)

    def Save(self, fname=None, positions=None):
        o = []
        # print 'Save CONFIG FILE:', fname, os.getcwd()
        # print positions.keys()
        cnf = self.config

        if fname is not None:
            self.filename = fname
        o.append('## Sample Stage Configuration (saved: %s)'  % (time.ctime()))

        if positions is None:
            positions = cnf['positions']
        for sect, optlist in conf_objs.items():
            o.append('#--------------------------#\n[%s]'%sect)
            if sect == 'positions' and positions is not None:
                o.append(POS_LEGEND)
                fmt =  "%3.3i = %s || %s || %s "
                pfmt =  ', '.join(['%f' for i in range(self.nstages)])
                idx = 1
                for name, val in positions.items():
                    pos = []
                    for pvname in cnf['stages']:
                        try:
                            pos.append(float(val['position'][pvname]))
                        except:
                            pass
                    pfmt =  ', '.join(['%f' for i in range(len(pos))])
                    pos = pfmt % tuple(pos)
                    try:
                        tmpdir, imgfile = os.path.split(val['image'])
                    except:
                        tmpdir, imgfile = '', ''

                    o.append(fmt % (idx, name, imgfile, pos))
                    idx = idx + 1
            elif sect == 'stages':
                o.append(STAGE_LEGEND)
                fmt =  "%i = %s || %s || %s || %s || %s || %s || %s"
                idx = 1
                for name, dat in cnf['stages'].items():
                    # print 'Save STAGE ', name, dat
                    # index =  motor || group   ||desc || scale || prec || maxstep || show
                    group = dat['group']
                    desc  = dat['desc']
                    show  = str(dat['show'])
                    scale  = str(dat['scale'])
                    prec   = str(dat['prec'])
                    maxstep  = "%.3f" % (dat['maxstep'])
                    o.append(fmt % (idx, name, group, desc, scale, prec, maxstep, show))
                    idx = idx + 1
            if optlist is not None:
                for opt in optlist:
                    try:
                        val = cnf[sect].get(opt,' ')
                        if not isinstance(val,(str,unicode)): val = str(val)
                        o.append("%s = %s" % (opt,val))
                    except:
                        pass
        o.append('#------------------#\n')
        # print 'Conf autosave ', fname
        # print os.path.abspath(fname)
        f = open(fname,'w')
        f.write('\n'.join(o))
        f.close()

    def sections(self):
        return self.config.keys()

    def section(self,section):
        return self.config[section]

    def get(self,section,value=None):
        if value is None:
            return self.config[section]
        else:
            return self.config[section][value]
               
if os.path.isfile('config.ini'):
    config = ConfigParser()
    config.read('config.ini')
else:
    config = None
# load default values from config.ini, if exists
if config:
    opt.set_defaults(**dict(config.items('firehose')))

options, args = opt.parse_args()

# load preset option values from config
if options.preset:
    if config:
        if config.has_section(options.preset):
            options._update_careful(dict(config.items(options.preset)))
        else:
            opt.error("no preset {!r} is defined".format(options.preset))
    else:
        opt.error("--preset is specified, but there's no ./config.ini")

logopts = dict(level=logging.INFO,
               datefmt='%FT%T',
               format='%(asctime)s %(levelname)s %(message)s')
if options.logfile:
    logopts['filename'] = options.logfile
logging.basicConfig(**logopts)

if len(args) < 1:
    endpoint = options.endpoint
Ejemplo n.º 36
0
class SetupConfig(object):
    """Wrapper around the setup.cfg file if available.

    One reason is to cleanup setup.cfg from these settings::

        [egg_info]
        tag_build = dev
        tag_svn_revision = true

    Another is for optional zest.releaser-specific settings::

        [zest.releaser]
        no-input = yes


    """

    config_filename = SETUP_CONFIG_FILE

    def __init__(self):
        """Grab the configuration (overridable for test purposes)"""
        # If there is a setup.cfg in the package, parse it
        if not os.path.exists(os.path.join(utils.PACKAGE_ROOT, self.config_filename)):
            self.config = None
            return
        self.config = ConfigParser()
        with codecs.open(self.config_filename, 'r', 'utf8') as fp:
            self.config.readfp(fp)

    def has_bad_commands(self):
        if self.config is None:
            return False
        if not self.config.has_section('egg_info'):
            # bail out early as the main section is not there
            return False
        bad = False
        # Check 1.
        if self.config.has_option('egg_info', 'tag_build'):
            # Might still be empty.
            value = self.config.get('egg_info', 'tag_build')
            if value:
                logger.warn("%s has [egg_info] tag_build set to %r",
                            self.config_filename, value)
                bad = True
        # Check 2.
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            if self.config.getboolean('egg_info', 'tag_svn_revision'):
                value = self.config.get('egg_info', 'tag_svn_revision')
                logger.warn("%s has [egg_info] tag_svn_revision set to %r",
                            self.config_filename, value)
                bad = True
        return bad

    def fix_config(self):
        if not self.has_bad_commands():
            logger.warn("Cannot fix already fine %s.", self.config_filename)
            return
        if self.config.has_option('egg_info', 'tag_build'):
            self.config.set('egg_info', 'tag_build', '')
        if self.config.has_option('egg_info', 'tag_svn_revision'):
            self.config.set('egg_info', 'tag_svn_revision', 'false')
        new_setup = open(self.config_filename, 'w')
        try:
            self.config.write(new_setup)
        finally:
            new_setup.close()
        logger.info("New setup.cfg contents:")
        print(''.join(open(self.config_filename).readlines()))

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        default = False
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'no-input')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def python_file_with_version(self):
        """Return Python filename with ``__version__`` marker, if configured.

        Enable this by adding a ``python-file-with-version`` option::

            [zest.releaser]
            python-file-with-version = reinout/maurits.py

        Return None when nothing has been configured.

        """
        default = None
        if self.config is None:
            return default
        try:
            result = self.config.get(
                'zest.releaser',
                'python-file-with-version')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 37
0
 def _get_names_from_config(self, cp, section):
     config = ConfigParser()
     config.read(cp)
     if config.has_section(section):
         return [config.get(section, option) for option in config.options(section)]
Ejemplo n.º 38
0
class PypiConfig(object):
    """Wrapper around the pypi config file"""
    def __init__(self, config_filename=DIST_CONFIG_FILE, use_setup_cfg=True):
        """Grab the PyPI configuration.

        This is .pypirc in the home directory.  It is overridable for
        test purposes.

        If there is a setup.cfg file in the current directory, we read
        it too.
        """
        self.config_filename = config_filename
        self.use_setup_cfg = use_setup_cfg
        self.reload()

    def reload(self):
        """Load the config.

        Do the initial load of the config.

        Or reload it in case of problems: this is needed when a pypi
        upload fails, you edit the .pypirc file to fix the account
        settings, and tell release to retry the command.
        """
        self._read_configfile(use_setup_cfg=self.use_setup_cfg)

    def _read_configfile(self, use_setup_cfg=True):
        """Read the PyPI config file and store it (when valid).

        Usually read the setup.cfg too.
        """
        rc = self.config_filename
        if not os.path.isabs(rc):
            rc = os.path.join(os.path.expanduser('~'), self.config_filename)
        filenames = [rc]
        if use_setup_cfg:
            # If there is a setup.cfg in the package, parse it
            filenames.append('setup.cfg')
        files = [f for f in filenames if os.path.exists(f)]
        if not files:
            self.config = None
            return
        self.config = ConfigParser()
        for filename in files:
            with codecs.open(filename, 'r', 'utf8') as fp:
                self.config.readfp(fp)

    def is_pypi_configured(self):
        # Do we have configuration for releasing to at least one
        # pypi-compatible server?
        if self.config is None:
            return False
        return len(self.distutils_servers()) > 0

    def get_server_config(self, server):
        """Get url, username, password for server.
        """
        repository_url = DEFAULT_REPOSITORY
        username = None
        password = None
        if self.config.has_section(server):
            if self.config.has_option(server, 'repository'):
                repository_url = self.config.get(server, 'repository')
            if self.config.has_option(server, 'username'):
                username = self.config.get(server, 'username')
            if self.config.has_option(server, 'password'):
                password = self.config.get(server, 'password')
        if not username and self.config.has_option('server-login', 'username'):
            username = self.config.get('server-login', 'username')
        if not password and self.config.has_option('server-login', 'password'):
            password = self.config.get('server-login', 'password')
        return {
            'repository_url': repository_url,
            'username': username,
            'password': password,
        }

    def distutils_servers(self):
        """Return a list of known distutils servers.

        If the config has an old pypi config, remove the default pypi
        server from the list.
        """
        try:
            index_servers = self.config.get('distutils',
                                            'index-servers').split()
        except (NoSectionError, NoOptionError):
            index_servers = []
        if not index_servers:
            # If no distutils index-servers have been given, 'pypi' should be
            # the default.  This is what twine does.
            if self.config.has_option('server-login', 'username'):
                # We have a username, so upload to pypi should work fine, even
                # when no explicit pypi section is in the file.
                return ['pypi']
            # https://github.com/zestsoftware/zest.releaser/issues/199
            index_servers = ['pypi']
        # The servers all need to have a section in the config file.
        return [
            server for server in index_servers
            if self.config.has_section(server)
        ]

    def want_release(self):
        """Does the user normally want to release this package.

        Some colleagues find it irritating to have to remember to
        answer the question "Check out the tag (for tweaks or
        pypi/distutils server upload)" with the non-default 'no' when
        in 99 percent of the cases they just make a release specific
        for a customer, so they always answer 'no' here.  This is
        where an extra config option comes in handy: you can influence
        the default answer so you can just keep hitting 'Enter' until
        zest.releaser is done.

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want the default answer to this
        question to be 'no':

        [zest.releaser]
        release = no

        The default when this option has not been set is True.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        return self._get_boolean('zest.releaser', 'release', default=True)

    def extra_message(self):
        """Return extra text to be added to commit messages.

        This can for example be used to skip CI builds.  This at least
        works for Travis.  See
        http://docs.travis-ci.com/user/how-to-skip-a-build/

        Enable this mode by adding a ``extra-message`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            extra-message = [ci skip]
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self.config.get('zest.releaser', 'extra-message')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def create_wheel(self):
        """Should we create a Python wheel for this package?

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want to create a Python wheel, next
        to a standard sdist:

        [zest.releaser]
        create-wheel = yes

        """
        if not USE_WHEEL:
            # If the wheel package is not available, we obviously
            # cannot create wheels.
            return False
        return self._get_boolean('zest.releaser', 'create-wheel')

    def register_package(self):
        """Should we try to register this package with a package server?

        For the standard Python Package Index (PyPI), registering a
        package is no longer needed: this is done automatically when
        uploading a distribution for a package.  In fact, trying to
        register may fail.  See
        https://github.com/zestsoftware/zest.releaser/issues/191
        So by default zest.releaser will no longer register a package.

        But you may be using your own package server, and registering
        may be wanted or even required there.  In this case
        you will need to turn on the register function.
        In your setup.cfg or ~/.pypirc, use the following to ensure that
        register is called on the package server:

        [zest.releaser]
        register = yes

        Note that if you have specified multiple package servers, this
        option is used for all of them.  There is no way to register and
        upload to server A, and only upload to server B.
        """
        return self._get_boolean('zest.releaser', 'register')

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.
        """
        return self._get_boolean('zest.releaser', 'no-input')

    def development_marker(self):
        """Return development marker to be appended in postrelease.

        Override the default ``.dev0`` in setup.cfg using
        a ``development-marker`` option::

            [zest.releaser]
            development-marker = .dev1

        Returns default of ``.dev0`` when nothing has been configured.
        """
        default = '.dev0'
        if self.config is None:
            return default
        try:
            result = self.config.get('zest.releaser', 'development-marker')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def push_changes(self):
        """Return whether the user wants to push the changes to the remote.

        Configure this mode by adding a ``push-changes`` option::

            [zest.releaser]
            push-changes = no

        The default when this option has not been set is True.
        """
        return self._get_boolean('zest.releaser', 'push-changes', default=True)

    def less_zeroes(self):
        """Return whether the user prefers less zeroes at the end of a version.

        Configure this mode by adding a ``less-zeroes`` option::

            [zest.releaser]
            less-zeroes = yes

        The default when this option has not been set is False.

        When set to true:
        - Instead of 1.3.0 we will suggest 1.3.
        - Instead of 2.0.0 we will suggest 2.0.

        This only makes sense for the bumpversion command.
        In the postrelease command we read this option too,
        but with the current logic it has no effect there.
        """
        return self._get_boolean('zest.releaser', 'less-zeroes')

    def version_levels(self):
        """How many levels does the user prefer in a version number?

        Configure this mode by adding a ``version-levels`` option::

            [zest.releaser]
            version-levels = 3

        The default when this option has not been set is 0, which means:
        no preference, so use the length of the current number.

        This means when suggesting a next version after 1.2:
        - with levels=0 we will suggest 1.3: no change
        - with levels=1 we will still suggest 1.3, as we will not
          use this to remove numbers, only to add them
        - with levels=2 we will suggest 1.3
        - with levels=3 we will suggest 1.2.1

        If the current version number has more levels, we keep them.
        So next version for 1.2.3.4 with levels=1 is 1.2.3.5.

        Tweaking version-levels and less-zeroes should give you the
        version number strategy that you prefer.
        """
        default = 0
        if self.config is None:
            return default
        try:
            result = self.config.getint('zest.releaser', 'version-levels')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        if result < 0:
            return default
        return result

    def _get_boolean(self, section, key, default=False):
        """Get a boolean from the config.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        result = default
        if self.config is not None:
            try:
                result = self.config.getboolean(section, key)
            except (NoSectionError, NoOptionError, ValueError):
                return result
        return result
Ejemplo n.º 39
0
class PypiConfig(object):
    """Wrapper around the pypi config file"""
    def __init__(self, config_filename=DIST_CONFIG_FILE, use_setup_cfg=True):
        """Grab the PyPI configuration.

        This is .pypirc in the home directory.  It is overridable for
        test purposes.

        If there is a setup.cfg file in the current directory, we read
        it too.
        """
        self.config_filename = config_filename
        self._read_configfile(use_setup_cfg=use_setup_cfg)

    def _read_configfile(self, use_setup_cfg=True):
        """Read the PyPI config file and store it (when valid).

        Usually read the setup.cfg too.
        """
        rc = self.config_filename
        if not os.path.isabs(rc):
            rc = os.path.join(os.path.expanduser('~'), self.config_filename)
        filenames = [rc]
        if use_setup_cfg:
            # If there is a setup.cfg in the package, parse it
            filenames.append('setup.cfg')
        files = [f for f in filenames if os.path.exists(f)]
        if not files:
            self.config = None
            return
        self.config = ConfigParser()
        for filename in files:
            with codecs.open(filename, 'r', 'utf8') as fp:
                self.config.readfp(fp)

    def is_pypi_configured(self):
        # Do we have configuration for releasing to at least one
        # pypi-compatible server?
        if self.config is None:
            return False
        if self.is_old_pypi_config():
            return True
        if self.is_new_pypi_config() and len(self.distutils_servers()) > 0:
            return True
        return False

    def is_old_pypi_config(self):
        if self.config is None:
            return False
        try:
            self.config.get('server-login', 'username')
        except (NoSectionError, NoOptionError):
            return False
        return True

    def is_new_pypi_config(self):
        try:
            self.config.get('distutils', 'index-servers')
        except (NoSectionError, NoOptionError):
            return False
        return True

    def get_server_config(self, server):
        """Get url, username, password for server.
        """
        repository_url = DEFAULT_REPOSITORY
        username = None
        password = None
        if self.config.has_section(server):
            if self.config.has_option(server, 'repository'):
                repository_url = self.config.get(server, 'repository')
            if self.config.has_option(server, 'username'):
                username = self.config.get(server, 'username')
            if self.config.has_option(server, 'password'):
                password = self.config.get(server, 'password')
        if not username and self.config.has_option('server-login', 'username'):
            username = self.config.get('server-login', 'username')
        if not password and self.config.has_option('server-login', 'password'):
            password = self.config.get('server-login', 'password')
        return {
            'repository_url': repository_url,
            'username': username,
            'password': password,
        }

    def distutils_servers(self):
        """Return a list of known distutils servers.

        If the config has an old pypi config, remove the default pypi
        server from the list.
        """
        try:
            raw_index_servers = self.config.get('distutils', 'index-servers')
        except (NoSectionError, NoOptionError):
            return []
        ignore_servers = ['']
        if self.is_old_pypi_config():
            # We have already asked about uploading to pypi using the normal
            # upload.
            ignore_servers.append('pypi')
            # Yes, you can even have an old pypi config with a
            # [distutils] server list.
        index_servers = [
            server.strip() for server in raw_index_servers.split('\n')
            if server.strip() not in ignore_servers
        ]
        return index_servers

    def want_release(self):
        """Does the user normally want to release this package.

        Some colleagues find it irritating to have to remember to
        answer the question "Check out the tag (for tweaks or
        pypi/distutils server upload)" with the non-default 'no' when
        in 99 percent of the cases they just make a release specific
        for a customer, so they always answer 'no' here.  This is
        where an extra config option comes in handy: you can influence
        the default answer so you can just keep hitting 'Enter' until
        zest.releaser is done.

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want the default answer to this
        question to be 'no':

        [zest.releaser]
        release = no

        The default when this option has not been set is True.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        default = True
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'release')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def extra_message(self):
        """Return extra text to be added to commit messages.

        This can for example be used to skip CI builds.  This at least
        works for Travis.  See
        http://docs.travis-ci.com/user/how-to-skip-a-build/

        Enable this mode by adding a ``extra-message`` option, either in the
        package you want to release, or in your ~/.pypirc::

            [zest.releaser]
            extra-message = [ci skip]
        """
        default = ''
        if self.config is None:
            return default
        try:
            result = self.config.get('zest.releaser', 'extra-message')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def create_wheel(self):
        """Should we create a Python wheel for this package?

        Either in your ~/.pypirc or in a setup.cfg in a specific
        package, add this when you want to create a Python wheel, next
        to a standard sdist:

        [zest.releaser]
        create-wheel = yes

        """
        if not USE_WHEEL:
            # If the wheel package is not available, we obviously
            # cannot create wheels.
            return False
        default = False
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'create-wheel')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result

    def no_input(self):
        """Return whether the user wants to run in no-input mode.

        Enable this mode by adding a ``no-input`` option::

            [zest.releaser]
            no-input = yes

        The default when this option has not been set is False.

        Standard config rules apply, so you can use upper or lower or
        mixed case and specify 0, false, no or off for boolean False,
        and 1, on, true or yes for boolean True.
        """
        default = False
        if self.config is None:
            return default
        try:
            result = self.config.getboolean('zest.releaser', 'no-input')
        except (NoSectionError, NoOptionError, ValueError):
            return default
        return result
Ejemplo n.º 40
0
def load(cfg_file=None, environment=None, overrides=None):
    """
    Load configuration.

    A configuration file consists of sections, led by a ``[section]`` header
    and followed by ``name: value`` entries. Lines beginning with ``'#'`` are
    ignored and may be used to provide comments.

    A configuration file can contain multiple sections. The configuration
    object is populated with values from the ``global`` section and additional
    sections based on the fully qualified domain name of the local host. For
    example, on the host ``deployXXXX.eqiad.wmnet`` the final value for a given
    setting would be the first value found in sections:
    ``deployXXXX.eqiad.wmnet``, ``eqiad.wmnet``, ``wmnet`` or ``global``.
    Sections not present in the configuration file will be ignored.

    Configuration values are loaded from a file specified by the ``-c`` or
    ``--conf`` command-line options or from the default locations with the
    following hierarchy, sorted by override priority:

    #. ``$(pwd)/scap/environments/<environment>/scap.cfg`` or
       ``$(pwd)/scap/scap.cfg`` (if no environment was specified)
    #. ``/etc/scap.cfg``

    For example, if a configuration parameter is set in
    ``$(pwd)/scap/scap.cfg`` and that same parameter is set in
    ``/etc/scap.cfg`` the value for that parameter set in
    ``$(pwd)/scap/scap.cfg`` will be used during execution.

    :param cfg_file: Alternate configuration file
    :param environment: the string path under which scap.cfg is found
    :param overrides: Dict of configuration values
    :returns: dict of configuration values
    """
    local_cfg = os.path.join(os.getcwd(), 'scap')

    parser = ConfigParser()
    if cfg_file:
        try:
            cfg_file = open(cfg_file)
        except TypeError:
            # Assume that cfg_file is already an open file
            pass

        if hasattr(parser, 'read_file'):
            parser.read_file(cfg_file)
        else:
            parser.readfp(cfg_file)
    else:
        parser.read([
            '/etc/scap.cfg',
            os.path.join(local_cfg, 'scap.cfg'),
            utils.get_env_specific_filename(
                os.path.join(local_cfg, 'scap.cfg'), environment)
        ])

    fqdn = socket.getfqdn().split('.')
    sections = ['global']
    sections += ['.'.join(fqdn[x:]) for x in range(0, len(fqdn))][::-1]

    config = {key: value for key, (_, value) in DEFAULT_CONFIG.items()}

    for section in sections:
        if parser.has_section(section):
            # Do not interpolate items in the section.
            # Fixes crash on deployment server:
            #   'int' object has no attribute 'find'
            for key, value in parser.items(section, True):
                config[key] = coerce_value(key, value)

    config = override_config(config, overrides)

    if not environment and config.get('environment', None):
        return load(cfg_file, config.get('environment'), overrides)

    config['environment'] = environment
    return config
Ejemplo n.º 41
0
class InstrumentConfig(object):
    basename = 'epics_insts'
    sections = ('dbs',)

    def __init__(self, name=None):
        self.conffile = name
        if name is None:
            self.conffile = os.path.join(get_appdir(self.basename),
                                         'config.ini')
        self.conf = {}
        self.cp =  ConfigParser()
        self.read()

    def read(self):
        for s in self.sections:
            self.conf[s] = {}
        if not os.path.exists(self.conffile):
            self.cp.readfp(StringIO(default_config))
        self.cp.read(self.conffile)

        for sect in self.sections:
            if self.cp.has_section(sect):
                for opt in self.cp.options(sect):
                    if opt is None:
                        continue
                    self.conf[sect][opt] = self.cp.get(sect, opt)

    def write(self, fname=None):
        if fname is None:
            fname = self.conffile
        out = []
        for sect in self.sections:
            out.append('[%s]\n' % sect)
            if sect == 'dbs':
                maxcount = 10
            if sect in self.conf:
                count = 0
                for key in sorted(self.conf[sect]):
                    val = self.conf[sect][key]
                    if count < maxcount:
                        out.append('%s = %s\n' % (key, val))
                        count += 1

        fout = open(fname, 'w')
        fout.writelines(out)
        fout.close()

    def get_dblist(self):
        dblist = [self.conf['dbs'].get('most_recent', '')]
        for key in sorted(self.conf['dbs'].keys()):
            val = self.conf['dbs'][key]
            if val is None: continue
            val = val.strip()
            if (key != 'most_recent' and len(val) > 0):
                dblist.append(val)
        return dblist

    def set_current_db(self, dbname):
        dblist = self.get_dblist()
        idx = 1
        newlist = [dbname]
        for name in dblist:
            if len(name.strip()) > 0 and name not in newlist:
                key = 'v%2.2i' % idx
                self.conf['dbs'][key] = name
                idx += 1

        self.conf['dbs']['most_recent'] = dbname
Ejemplo n.º 42
0
class SpecConfig(object):
    #  sections            name      ordered?
    __sects = OrderedDict((('setup',     False),
                           ('motors',    True),
                           ('detectors', True),
                           ('extra_pvs', True),
                           ('counters',  True)))

    def __init__(self, filename=None, text=None):
        for s in self.__sects:
            setattr(self, s, {})

        self._cp = ConfigParser()
        if filename is None:
            if (os.path.exists(DEF_CONFFILE) and
                os.path.isfile(DEF_CONFFILE)):
                filename = DEF_CONFFILE

        self.filename = filename
        if filename is not None:
            self.Read(filename)

    def Read(self, fname):
        "read config"
        if fname is None:
            return
        ret = self._cp.read(fname)
        if len(ret) == 0:
            time.sleep(0.25)
            ret = self._cp.read(fname)
        self.filename = fname
        # process sections
        for sect, ordered in self.__sects.items():
            if not self._cp.has_section(sect):
                continue
            thissect = {}
            if ordered:
                thissect = OrderedDict()
            for opt in self._cp.options(sect):
                val = self._cp.get(sect, opt)
                if '||' in val:
                    words = [i.strip() for i in val.split('||')]
                    label = words.pop(0)
                    if len(words) == 1:
                        words = words[0]
                    else:
                        words = tuple(words)
                    thissect[label] = words
                else:
                    thissect[opt] = val
                setattr(self, sect, thissect)

    def Save(self, fname=None):
        "save config file"
        if fname is not None:
            self.filename = fname
        if fname is None:
            fname = self.filename = DEF_CONFFILE
            path, fn = os.path.split(fname)
            if not os.path.exists(path):
                os.makedirs(path, mode=0o755)

        out = ['###PyScan Spec Configuration: %s'  % (get_timestamp())]
        for sect, ordered in self.__sects.items():
            out.append('#-----------------------#\n[%s]' % sect)
            if sect == 'setup':
                for name, val in self.setup.items():
                    out.append("%s = %s" % (name, val))
            elif sect == 'detectors':
                out.append(DET_LEGEND)
                print( 'sect = det')
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        val = ' || '.join(val)
                    out.append("%i = %s || %s"  % (idx, key, val))

            else:
                leg = LEGEND
                out.append(LEGEND)
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        val = ' || '.join(val)
                    out.append("%i = %s || %s"  % (idx, key, val))
        out.append('#-----------------------#')
        f = open(fname, 'w')
        f.write('\n'.join(out))
        f.close()

    def sections(self):
        return self.__sects.keys()
Ejemplo n.º 43
0
class OpenLDAP2:
  library_dirs = []
  include_dirs = []
  extra_compile_args = []
  extra_link_args = []
  extra_objects = []
  libs = ['ldap', 'lber']
  defines = [ ]
  extra_files = []

LDAP_CLASS = OpenLDAP2

#-- Read the [_ldap] section of setup.cfg
cfg = ConfigParser()
cfg.read('setup.cfg')
if cfg.has_section('_ldap'):
  for name in dir(LDAP_CLASS):
    if cfg.has_option('_ldap', name):
      print(name + ': ' + cfg.get('_ldap', name))
      setattr(LDAP_CLASS, name, cfg.get('_ldap', name).split())

for i in range(len(LDAP_CLASS.defines)):
  LDAP_CLASS.defines[i]=((LDAP_CLASS.defines[i],None))

for i in range(len(LDAP_CLASS.extra_files)):
  destdir, origfiles = LDAP_CLASS.extra_files[i].split(':')
  origfileslist = origfiles.split(',')
  LDAP_CLASS.extra_files[i]=(destdir, origfileslist)

#-- Let distutils/setuptools do the rest
name = 'python-ldap'
Ejemplo n.º 44
0
class InstrumentConfig(object):
    basename = 'epics_insts'
    sections = ('dbs', )

    def __init__(self, name=None):
        self.conffile = name
        if name is None:
            self.conffile = os.path.join(get_appdir(self.basename),
                                         'config.ini')
        self.conf = {}
        self.cp = ConfigParser()
        self.read()

    def read(self):
        for s in self.sections:
            self.conf[s] = {}
        if not os.path.exists(self.conffile):
            self.cp.readfp(StringIO(default_config))
        self.cp.read(self.conffile)

        for sect in self.sections:
            if self.cp.has_section(sect):
                for opt in self.cp.options(sect):
                    if opt is None:
                        continue
                    self.conf[sect][opt] = self.cp.get(sect, opt)

    def write(self, fname=None):
        if fname is None:
            fname = self.conffile
        out = []
        for sect in self.sections:
            out.append('[%s]\n' % sect)
            if sect == 'dbs':
                maxcount = 10
            if sect in self.conf:
                count = 0
                for key in sorted(self.conf[sect]):
                    val = self.conf[sect][key]
                    if count < maxcount:
                        out.append('%s = %s\n' % (key, val))
                        count += 1

        fout = open(fname, 'w')
        fout.writelines(out)
        fout.close()

    def get_dblist(self):
        dblist = [self.conf['dbs'].get('most_recent', '')]
        for key in sorted(self.conf['dbs'].keys()):
            val = self.conf['dbs'][key]
            if val is None: continue
            val = val.strip()
            if (key != 'most_recent' and len(val) > 0):
                dblist.append(val)
        return dblist

    def set_current_db(self, dbname):
        dblist = self.get_dblist()
        idx = 1
        newlist = [dbname]
        for name in dblist:
            if len(name.strip()) > 0 and name not in newlist:
                key = 'v%2.2i' % idx
                self.conf['dbs'][key] = name
                idx += 1

        self.conf['dbs']['most_recent'] = dbname
Ejemplo n.º 45
0
class StationConfig(object):
    #  sections            name      ordered?
    __sects = OrderedDict((
        ('setup', False),
        ('server', False),
        ('positioners', True),
        ('detectors', True),
        ('counters', True),
        ('xafs', False),
        ('slewscan', False),
        ('slewscan_positioners', True),
        ('extrapvs', True),
    ))

    def __init__(self, filename=None, text=None):
        for s in self.__sects:
            setattr(self, s, {})

        self._cp = ConfigParser()
        if filename is None:
            filename = DEF_CONFFILE
        self.filename = filename
        # print 'StationConfig ', filename, os.path.abspath(filename)
        # print os.path.exists(filename),   os.path.isfile(filename)
        if (os.path.exists(filename) and os.path.isfile(filename)):
            ret = self._cp.read(filename)
            if len(ret) == 0:
                time.sleep(0.1)
                self._cp.read(filename)
        else:
            self._cp.readfp(StringIO(DEFAULT_CONF))
        self.Read()

    def Read(self, filename=None):
        "read config"
        if (filename is not None
                and (os.path.exists(filename) and os.path.isfile(filename))):
            ret = self._cp.read(filename)
            if len(ret) == 0:
                time.sleep(0.1)
                self._cp.read(filename)
            self.filename = filename

        # process sections
        for sect, ordered in self.__sects.items():
            if not self._cp.has_section(sect):
                continue
            thissect = {}
            opt_keys = self._cp.options(sect)
            if ordered:
                thissect = OrderedDict()
                opt_keys.sort()
            for opt in opt_keys:
                val = self._cp.get(sect, opt)
                if '||' in val:
                    words = [i.strip() for i in val.split('||')]
                    label = words.pop(0)
                    if len(words) == 1:
                        words = words[0]
                    else:
                        tmp = []
                        for w in words:
                            if ',' in w and '=' in w:
                                tmp.append(opts2dict(w))
                            else:
                                tmp.append(w)
                        words = tuple(tmp)
                    thissect[label] = words
                else:
                    thissect[opt] = val
                setattr(self, sect, thissect)
        for key, val in self.positioners.items():
            fi = []
            if isinstance(val, (list, tuple)):
                for v in val:
                    if '.' not in v: v = '%s.VAL' % v
                    fi.append(v)
            else:
                if '.' not in val:
                    val = '%s.VAL' % val
                fi = [val, val]
            self.positioners[key] = tuple(fi)

    def Save(self, fname=None):
        "save config file"
        if fname is not None:
            self.filename = fname
        if fname is None:
            fname = self.filename = DEF_CONFFILE
            path, fn = os.path.split(fname)
            if not os.path.exists(path):
                os.makedirs(path, mode=0o755)

        out = ['### %s: %s' % (TITLE, get_timestamp())]
        for sect, ordered in self.__sects.items():
            out.append('#------------------------------#\n[%s]' % sect)
            if sect in ('setup', 'server', 'slewscan', 'xafs'):
                for name, val in self.setup.items():
                    out.append("%s = %s" % (name, val))
            elif sect == 'detectors':
                out.append(DET_LEGEND)
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        wout = []
                        for w in val:
                            if isinstance(w, dict):
                                wout.append(dict2opts(w))
                            elif isinstance(w, (str, unicode)):
                                wout.append(w)
                            else:
                                wout.append(repr(w))
                        val = ' || '.join(wout)
                    out.append("%i = %s || %s" % (idx, key, val))

            else:
                leg = LEGEND
                out.append(LEGEND)
                idx = 0
                for key, val in getattr(self, sect).items():
                    idx = idx + 1
                    if isinstance(val, (list, tuple)):
                        val = ' || '.join(val)
                    out.append("%i = %s || %s" % (idx, key, val))
        out.append('#-----------------------#')
        f = open(fname, 'w')
        f.write('\n'.join(out))
        f.close()

    def sections(self):
        return self.__sects.keys()