From a7f9df6dac32d2efd31b1c84ce10981560913282 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 26 Oct 2011 20:13:12 -0700 Subject: Add public news functions for bug #388233. count_unread_news(portdb, vardb, repos=None, update=True) display_news_notifications(news_counts) --- pym/_emerge/actions.py | 78 +++++++------------------------------------------- pym/portage/news.py | 72 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 68 deletions(-) (limited to 'pym') diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 5485d755c..88f595866 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -21,16 +21,20 @@ import time from itertools import chain import portage +portage.proxy.lazyimport.lazyimport(globals(), + 'portage.news:count_unread_news,display_news_notifications', +) + from portage import os from portage import subprocess_getstatusoutput from portage import _unicode_decode from portage.cache.cache_errors import CacheError -from portage.const import GLOBAL_CONFIG_PATH, NEWS_LIB_PATH +from portage.const import GLOBAL_CONFIG_PATH from portage.const import _ENABLE_DYN_LINK_MAP, _ENABLE_SET_CONFIG from portage.dbapi.dep_expand import dep_expand from portage.dbapi._expand_new_virt import expand_new_virt from portage.dep import Atom, extended_cp_match -from portage.exception import InvalidAtom, PermissionDenied +from portage.exception import InvalidAtom from portage.output import blue, bold, colorize, create_color_func, darkgreen, \ red, yellow good = create_color_func("GOOD") @@ -3021,46 +3025,12 @@ def chk_updated_cfg_files(eroot, config_protect): print(" "+yellow("*")+" man page to learn how to update config files.") def display_news_notification(root_config, myopts): - target_root = root_config.settings['EROOT'] - trees = root_config.trees - settings = trees["vartree"].settings - portdb = trees["porttree"].dbapi - vardb = trees["vartree"].dbapi - NEWS_PATH = os.path.join("metadata", "news") - UNREAD_PATH = os.path.join(target_root, NEWS_LIB_PATH, "news") - newsReaderDisplay = False - if "news" not in settings.features: + if "news" not in root_config.settings.features: return - - permission_msgs = set() - for repo in portdb.getRepositories(): - try: - unreadItems = checkUpdatedNewsItems( - portdb, vardb, NEWS_PATH, UNREAD_PATH, repo, update=True) - except PermissionDenied as e: - # NOTE: The NewsManager typically handles permission errors by - # returning silently, so PermissionDenied won't necessarily be - # raised even if we do trigger a permission error above. - msg = _unicode_decode("Permission denied: '%s'\n") % (e,) - if msg in permission_msgs: - pass - else: - permission_msgs.add(msg) - writemsg_level(msg, level=logging.ERROR, noiselevel=-1) - unreadItems = None - - if unreadItems: - if not newsReaderDisplay: - newsReaderDisplay = True - print() - print(colorize("WARN", " * IMPORTANT:"), end=' ') - print("%s news items need reading for repository '%s'." % (unreadItems, repo)) - - - if newsReaderDisplay: - print(colorize("WARN", " *"), end=' ') - print("Use " + colorize("GOOD", "eselect news") + " to read news items.") - print() + portdb = root_config.trees["porttree"].dbapi + vardb = root_config.trees["vartree"].dbapi + news_counts = count_unread_news(portdb, vardb) + display_news_notifications(news_counts) def getgccversion(chost): """ @@ -3092,29 +3062,3 @@ def getgccversion(chost): portage.writemsg(gcc_not_found_error, noiselevel=-1) return "[unavailable]" - -def checkUpdatedNewsItems(portdb, vardb, NEWS_PATH, UNREAD_PATH, repo_id, - update=False): - """ - Examines news items in repodir + '/' + NEWS_PATH and attempts to find unread items - Returns the number of unread (yet relevent) items. - - @param portdb: a portage tree database - @type portdb: pordbapi - @param vardb: an installed package database - @type vardb: vardbapi - @param NEWS_PATH: - @type NEWS_PATH: - @param UNREAD_PATH: - @type UNREAD_PATH: - @param repo_id: - @type repo_id: - @rtype: Integer - @returns: - 1. The number of unread but relevant news items. - - """ - from portage.news import NewsManager - manager = NewsManager(portdb, vardb, NEWS_PATH, UNREAD_PATH) - return manager.getUnreadItems( repo_id, update=update ) - diff --git a/pym/portage/news.py b/pym/portage/news.py index 13d68324d..24b51072b 100644 --- a/pym/portage/news.py +++ b/pym/portage/news.py @@ -2,24 +2,30 @@ # Copyright 2006-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +from __future__ import print_function + __all__ = ["NewsManager", "NewsItem", "DisplayRestriction", "DisplayProfileRestriction", "DisplayKeywordRestriction", - "DisplayInstalledRestriction"] + "DisplayInstalledRestriction", + "count_unread_news", "display_news_notifications"] import io import logging import os as _os import re +from portage import OrderedDict from portage import os from portage import _encodings from portage import _unicode_decode from portage import _unicode_encode +from portage.const import NEWS_LIB_PATH from portage.util import apply_secpass_permissions, ensure_dirs, \ grabfile, normalize_path, write_atomic, writemsg_level from portage.data import portage_gid from portage.dep import isvalidatom from portage.localization import _ from portage.locks import lockfile, unlockfile +from portage.output import colorize from portage.exception import InvalidLocation, OperationNotPermitted, \ PermissionDenied @@ -349,3 +355,67 @@ class DisplayInstalledRestriction(DisplayRestriction): if vdb.match(self.atom): return True return False + +def count_unread_news(portdb, vardb, repos=None, update=True): + """ + Returns a dictionary mapping repos to integer counts of unread news items. + By default, this will scan all repos and check for new items that have + appeared since the last scan. + + @param portdb: a portage tree database + @type portdb: pordbapi + @param vardb: an installed package database + @type vardb: vardbapi + @param repos: names of repos to scan (None means to scan all available repos) + @type repos: list or None + @param update: check for new items (default is True) + @type update: boolean + @rtype: dict + @returns: dictionary mapping repos to integer counts of unread news items + """ + + NEWS_PATH = os.path.join("metadata", "news") + UNREAD_PATH = os.path.join(vardb.settings['EROOT'], NEWS_LIB_PATH, "news") + news_counts = OrderedDict() + if repos is None: + repos = portdb.getRepositories() + + permission_msgs = set() + for repo in repos: + try: + manager = NewsManager(portdb, vardb, NEWS_PATH, UNREAD_PATH) + count = manager.getUnreadItems(repo, update=True) + except PermissionDenied as e: + # NOTE: The NewsManager typically handles permission errors by + # returning silently, so PermissionDenied won't necessarily be + # raised even if we do trigger a permission error above. + msg = _unicode_decode("Permission denied: '%s'\n") % (e,) + if msg in permission_msgs: + pass + else: + permission_msgs.add(msg) + writemsg_level(msg, level=logging.ERROR, noiselevel=-1) + news_counts[repo] = 0 + else: + news_counts[repo] = count + + return news_counts + +def display_news_notifications(news_counts): + """ + Display a notification for unread news items, using a dictionary mapping + repos to integer counts, like that returned from count_unread_news(). + """ + newsReaderDisplay = False + for repo, count in news_counts.items(): + if count > 0: + if not newsReaderDisplay: + newsReaderDisplay = True + print() + print(colorize("WARN", " * IMPORTANT:"), end=' ') + print("%s news items need reading for repository '%s'." % (count, repo)) + + if newsReaderDisplay: + print(colorize("WARN", " *"), end=' ') + print("Use " + colorize("GOOD", "eselect news") + " to read news items.") + print() -- cgit v1.2.3-1-g7c22