# Copyright 2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import copy import io import logging import shelve import sys import time import portage from portage import os from portage.util import grabdict, grablines from portage.util._ShelveUnicodeWrapper import ShelveUnicodeWrapper class Config(object): def __init__(self, options, portdb, event_loop): self.options = options self.portdb = portdb self.event_loop = event_loop self.added_byte_count = 0 self.added_file_count = 0 self.scheduled_deletion_count = 0 self.delete_count = 0 self.file_owners = {} self.file_failures = {} self.start_time = time.time() self._open_files = [] self.log_success = self._open_log('success', options.success_log, 'a') self.log_failure = self._open_log('failure', options.failure_log, 'a') self.distfiles = None if options.distfiles is not None: self.distfiles = options.distfiles self.mirrors = copy.copy(portdb.settings.thirdpartymirrors()) if options.mirror_overrides is not None: self.mirrors.update(grabdict(options.mirror_overrides)) if options.mirror_skip is not None: for x in options.mirror_skip.split(","): self.mirrors[x] = [] self.whitelist = None if options.whitelist_from is not None: self.whitelist = set() for filename in options.whitelist_from: for line in grablines(filename): line = line.strip() if line and not line.startswith("#"): self.whitelist.add(line) self.restrict_mirror_exemptions = None if options.restrict_mirror_exemptions is not None: self.restrict_mirror_exemptions = frozenset( options.restrict_mirror_exemptions.split(",")) self.recycle_db = None if options.recycle_db is not None: self.recycle_db = self._open_shelve( options.recycle_db, 'recycle') self.distfiles_db = None if options.distfiles_db is not None: self.distfiles_db = self._open_shelve( options.distfiles_db, 'distfiles') self.deletion_db = None if options.deletion_db is not None: self.deletion_db = self._open_shelve( options.deletion_db, 'deletion') def _open_log(self, log_desc, log_path, mode): if log_path is None or self.options.dry_run: log_func = logging.info line_format = "%s: %%s" % log_desc add_newline = False if log_path is not None: logging.warn(("dry-run: %s log " "redirected to logging.info") % log_desc) else: self._open_files.append(io.open(log_path, mode=mode, encoding='utf_8')) line_format = "%s\n" log_func = self._open_files[-1].write return self._LogFormatter(line_format, log_func) class _LogFormatter(object): __slots__ = ('_line_format', '_log_func') def __init__(self, line_format, log_func): self._line_format = line_format self._log_func = log_func def __call__(self, msg): self._log_func(self._line_format % (msg,)) def _open_shelve(self, db_file, db_desc): if self.options.dry_run: open_flag = "r" else: open_flag = "c" if self.options.dry_run and not os.path.exists(db_file): db = {} else: db = shelve.open(db_file, flag=open_flag) if sys.hexversion < 0x3000000: db = ShelveUnicodeWrapper(db) if self.options.dry_run: logging.warn("dry-run: %s db opened in readonly mode" % db_desc) if not isinstance(db, dict): volatile_db = dict((k, db[k]) for k in db) db.close() db = volatile_db else: self._open_files.append(db) return db def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): while self._open_files: self._open_files.pop().close()