Attaches Purr to a purrlog directory, and loads content.
        Returns False if nothing new has been loaded (because directory is the same),
        or True otherwise.

def _attach(self, purrlog, watchdirs=None):
        """Attaches Purr to a purrlog directory, and loads content.
        Returns False if nothing new has been loaded (because directory is the same),
        or True otherwise."""
        purrlog = os.path.abspath(purrlog)
        dprint(1, "attaching to purrlog", purrlog)
        self.logdir = purrlog
        self.indexfile = os.path.join(self.logdir, "index.html")
        self.logtitle = "Unnamed log"
        self.timestamp = self.last_scan_timestamp = time.time()
        self._initIndexDir()
        # reset internal state
        self.ignorelistfile = None
        self.autopounce = False
        self.watched_dirs = []
        self.entries = []
        self._default_dp_props = {}
        self.watchers = {}
        self.temp_watchers = {}
        self.attached = False
        self._watching_state = {}
        # check that we hold a lock on the directory
        self.lockfile = os.path.join(self.logdir, ".purrlock")
        # try to open lock file for r/w
        try:
            self.lockfile_fd = os.open(self.lockfile, os.O_RDWR | os.O_CREAT)
        except:
            raise Purrer.LockFailError("failed to open lock file %s for writing" % self.lockfile)
        # try to acquire lock on the lock file
        try:
            fcntl.lockf(self.lockfile_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except:
            other_lock = os.fdopen(self.lockfile_fd, 'r').read()
            self.lockfile_fd = None
            raise Purrer.LockedError(other_lock)
        # got lock, write our ID to the lock file
        global _lockstring
        try:
            self.lockfile_fobj = os.fdopen(self.lockfile_fd, 'w')
            self.lockfile_fobj.write(_lockstring)
            self.lockfile_fobj.flush()
            os.fsync(self.lockfile_fd)
        except:
            raise
        #      raise Purrer.LockFailError("cannot write to lock file %s"%self.lockfile)
        # load log state if log directory already exists
        if os.path.exists(self.logdir):
            _busy = Purr.BusyIndicator()
            if os.path.exists(self.indexfile):
                try:
                    parser = Purr.Parsers.LogIndexParser()
                    for line in open(self.indexfile):
                        parser.feed(line)
                    self.logtitle = parser.title or self.logtitle
                    self.timestamp = parser.timestamp or self.timestamp
                    dprintf(2, "attached log '%s', timestamp %s\n",
                            self.logtitle, time.strftime("%x %X", time.localtime(self.timestamp)))
                except:
                    traceback.print_exc()
                    print("Error parsing %s, reverting to defaults" % self.indexfile)
            # load log entries
            entries = []
            for fname in os.listdir(self.logdir):
                pathname = os.path.join(self.logdir, fname)
                if Purr.LogEntry.isValidPathname(pathname):
                    try:
                        entry = Purr.LogEntry(load=pathname)
                        dprint(2, "loaded log entry", pathname)
                    except:
                        print("Error loading entry %s, skipping" % fname)
                        traceback.print_exc()
                        continue
                    entries.append(entry)
                else:
                    dprint(2, fname, "is not a valid Purr entry")
            # sort log entires by timestamp
            entries.sort(lambda a, b: cmp(a.timestamp, b.timestamp))
            self.setLogEntries(entries, save=False)
            # update own timestamp
            if entries:
                self.timestamp = max(self.timestamp, entries[-1].timestamp)
        # else logfile doesn't exist, create it
        else:
            self._initIndexDir()
        # load configuration if it exists
        # init config file
        self.dirconfig = configparser.RawConfigParser()
        self.dirconfigfile = os.path.join(self.logdir, "dirconfig")
        if os.path.exists(self.dirconfigfile):
            try:
                self.dirconfig.read(self.dirconfigfile)
            except:
                print("Error loading config file %s" % self.dirconfigfile)
                traceback.print_exc()
            # load directory configuration
            for dirname in self.dirconfig.sections():
                try:
                    watching = self.dirconfig.getint(dirname, "watching")
                except:
                    watching = Purr.WATCHED
                dirname = os.path.expanduser(dirname)
                self.addWatchedDirectory(dirname, watching, save_config=False)
        # start watching the specified directories
        for name in (watchdirs or []):
            self.addWatchedDirectory(name, watching=None)
        # Finally, go through list of ignored files and mark their watchers accordingly.
        # The ignorelist is a list of lines of the form "timestamp filename", giving the timestamp when a
        # file was last "ignored" by the purrlog user.
        self.ignorelistfile = os.path.join(self.logdir, "ignorelist")
        if os.path.exists(self.ignorelistfile):
            # read lines from file, ignore exceptions
            ignores = {}
            try:
                for line in open(self.ignorelistfile).readlines():
                    timestamp, policy, filename = line.strip().split(" ", 2)
                    # update dictiornary with latest timestamp
                    ignores[filename] = int(timestamp), policy
            except:
                print("Error reading %s" % self.ignorelistfile)
                traceback.print_exc()
            # now scan all listed files, and make sure their watchers' mtime is no older than the given
            # last-ignore-timestamp. This ensures that we don't pounce on these files after restarting purr.
            for filename, (timestamp, policy) in ignores.items():
                watcher = self.watchers.get(filename, None)
                if watcher:
                    watcher.mtime = max(watcher.mtime, timestamp)
        # init complete
        self.attached = True
        return True