Cleans up old hunt data from aff4.

def CleanAff4Hunts(self):
    """Cleans up old hunt data from aff4."""

    hunts_ttl = config.CONFIG["DataRetention.hunts_ttl"]
    if not hunts_ttl:
      self.Log("TTL not set - nothing to do...")
      return

    exception_label = config.CONFIG["DataRetention.hunts_ttl_exception_label"]

    hunts_root = aff4.FACTORY.Open("aff4:/hunts", token=self.token)
    hunts_urns = list(hunts_root.ListChildren())

    deadline = rdfvalue.RDFDatetime.Now() - hunts_ttl

    hunts_deleted = 0

    hunts = aff4.FACTORY.MultiOpen(
        hunts_urns, aff4_type=implementation.GRRHunt, token=self.token)
    for hunt in hunts:
      if exception_label in hunt.GetLabelsNames():
        continue

      runner = hunt.GetRunner()
      if runner.context.create_time + runner.context.duration < deadline:
        aff4.FACTORY.Delete(hunt.urn, token=self.token)
        hunts_deleted += 1
        self.HeartBeat()
    self.Log("Deleted %d hunts." % hunts_deleted)