| # 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() |