def __init__(self, conf, rradir, start=None, rrdapi=None, private=False):
        self._step = util.Interval(conf.get("repeat", "1m")).seconds
        self._ds_list = {'_state': {'type': "GAUGE", 'min': None, 'max': None}}
        # _ds_order is the order in the actual file and is set in validate()
        self._ds_order = None
        self._start = start

        if rrdapi is None:
            self._rrdapi = RRDTwistedAPI()
        else:
            self._rrdapi = rrdapi

        def parse_limit(new, old, key):
            limit = old.get(key, None)
            if limit is not None:
                try:
                    limit = float(limit)
                except ValueError:
                    raise errors.ConfigError(old,
                            "Invalid %s: %s" % (key, limit))
            new[key] = limit

        def parse_ds(ds_name, ds_conf):
            if 'trend' not in ds_conf or 'type' not in ds_conf['trend']:
                return

            ds_conf['trend'].expand()

            new = { 'type': ds_conf['trend.type'].upper() }
            if new['type'] not in self.TYPES:
                raise errors.ConfigError(ds_conf['trend'],
                        "Invalid type: %s" % new['type'])

            parse_limit(new, ds_conf['trend'], 'min')
            parse_limit(new, ds_conf['trend'], 'max')

            self._ds_list[ds_name] = new

        parse_ds('_result', conf)

        if conf['query.type'] == "compound":
            for subname, subconf in conf['query'].iteritems():
                if not isinstance(subconf, coil.struct.Struct):
                    continue
                parse_ds(subname, subconf)
        else:
            parse_ds('query', conf['query'])

        # Default to a 1 minute step when repeat is useless
        if self._step == 0:
            self._step = 60

        rras = conf.get('trend.rra', None)
        clean = re.compile('^[^\d]*').sub
        self._rras = self.RRAS.copy()
        if isinstance(rras, coil.struct.Struct):
            for interval, period in rras.iteritems():
                interval = clean('', interval)
                try:
                    interval = int(util.Interval(interval))
                except util.IntervalError:
                    raise errors.ConfigError(conf,
                            "Invalid RRA interval: %r" % interval)
                try:
                    period = int(util.Interval(period))
                except util.IntervalError:
                    raise errors.ConfigError(conf,
                            "Invalid RRA period: %r" % period)
                if not period:
                    del self._rras[interval]
                else:
                    self._rras[interval] = period
        elif rras is not None:
            raise errors.ConfigError(conf,
                    "trend.rra must be a struct, got: %r" % rras)

        self._rradir = os.path.abspath(os.path.join(rradir, conf['host']))
        self._rrafile = os.path.join(self._rradir, "%s.rrd" % conf['description'])

        if not os.path.exists(self._rradir):
            try:
                os.makedirs(self._rradir)
            except __HOLE__, ex:
                raise errors.InitError("Cannot create directory %s: %s" %
                        (self._rradir, ex))

        coil_file = os.path.join(self._rradir, "%s.coil" % conf['description'])
        # If the config is marked as private then we must make sure
        # it is not world readable. This impacts both access on the
        # local host and other tools such as Railroad.
        if private:
            mode = 0640
        else:
            mode = 0644
        try:
            coil_fd = os.open(
                coil_file, os.O_WRONLY|os.O_TRUNC|os.O_CREAT, mode)
            # Force a chmod/chown just in case the file already existed
            os.fchown(coil_fd, os.getuid(), os.getgid())
            os.fchmod(coil_fd, mode)
            os.write(coil_fd, '%s\n' % conf)
            os.close(coil_fd)
        except OSError, ex:
            raise errors.InitError("Cannot write to %s: %s" % (coil_file, ex))

        if os.path.exists(self._rrafile):
            try:
                self.validate()
            except MismatchError:
                self.replace()
        else:
            self.create()

        log.debug("Loaded trending config: %s", self._ds_list)
dataset/ETHPy150Open marineam/nagcat/python/nagcat/trend.py/Trend.__init__